SORU
6 ŞUBAT 2011, Pazar


Ne varsa bir liste içindeki bir öğeyi silmek için? (Python)

İle checkbox alanları self.response.get("new_tag") selected_tags ile form metin alanı new_tag alıyorum

self.response.get_all("selected_tags")

Ama onları böyle birleştirin:

tag_string = new_tag
new_tag_list = f1.striplist(tag_string.split(",")   selected_tags)

(f1.striplist listedeki dize içinde boşluk şeritler bir fonksiyonudur.)

Ama tag_list boş (yeni etiketler girilir) selected_tags, new_tag_list bazı vardır bu durumda boş bir dize içerir " ".

logging.info örneğin:

new_tag
selected_tags[u'Hello', u'Cool', u'Glam']
new_tag_list[u'', u'Hello', u'Cool', u'Glam']

Ne kadar boş dize kurtulurum?

Listedeki boş bir dize

>>> s = [u'', u'Hello', u'Cool', u'Glam']
>>> i = s.index("")
>>> del s[i]
>>> s
[u'Hello', u'Cool', u'Glam']

Ama eğer boş bir dizgi ise yok:

>>> s = [u'Hello', u'Cool', u'Glam']
>>> if s.index(""):
        i = s.index("")
        del s[i]
    else:
        print "new_tag_list has no empty string"

Ama bu verir:

Traceback (most recent call last):
  File "<pyshell#30>", line 1, in <module>
    if new_tag_list.index(""):
        ValueError: list.index(x): x not in list

Bunu neden ve nasıl bir çözüm? olur mu

CEVAP
6 ŞUBAT 2011, Pazar


1) Neredeyse İngiliz stili:

Varlığını Test in operatörü kullanarak remove yöntemi uygulayın.

if thing in some_list: some_list.remove(thing)

removeyöntemi if yerine while kullanabilirsiniz tüm oluşumları ortadan kaldırmak için thing, yalnızca ilk geçtiği kaldıracaktır.

while thing in some_list: some_list.remove(thing)    
  • Yeterince basit, muhtemelen benim seçimim.küçük listeleri (tek gömlekleri dayanamaz)

2) Duck-typed, EAFP stil:

Bu-ilk-ask-soru-son ateş tavır Python yaygındır. Eğer nesne uygun olup olmadığını önceden test etmek yerine, sadece işlemi yürütmek ve ilgili özel durumları yakalamak:

try:
    some_list.remove(thing)
except ValueError:
    pass # or scream: thing not in some_list!
except AttributeError:
    pass # call security, some_list not quacking like a list!

Eğer bir şey birden fazla kopyasını düşünüyorsanız:

while True:
    try:
        some_list.remove(thing)
    except ValueError:
        break
  • bu özel kullanım durumları için biraz ayrıntılı ama çok deyimsel Python.
  • bu #1 Daha iyi yapar
  • PEP 463 kullanışlı olacağını/dışında basit kullanım için daha kısa bir sözdizimi burada önerilen, ama onaylanmadı.

3) İşlevsel stil:

1993, Python etrafındalambda, reduce(), filter() map(), onları cevapsız ve çalışma yamalar* Gönderen Lisp bir hacker nezaket var. filter listeden öğeleri kaldırmak için kullanabilirsiniz:

is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)

Orada bir kısayol olabilir yararlı için durum: isterseniz filtre boş öğeleri (aslında öğeleri nerede bool(item) == False gibi None, sıfır, boş bir dize veya diğer boş koleksiyonları), iletebilirsiniz Hiçbiri olarak ilk bağımsız değişken:

cleaned_list = filter(None, some_list)
  • [güncelleme]: Python 2'de.x, filter(function, iterable) [item for item in iterable if function(item)] (ya da eğer ilk değişken None [item for item in iterable if item]); Python 3 için eşdeğer.x, şimdi (item for item in iterable if function(item)) eşdeğerdir. İnce fark olan filtre kullanılır dönmek listesi, şimdi çalışıyor gibi bir ifade jeneratör - TAMAM, eğer sen sadece üzerinden yineleme temizlenmiş listesi ve atarak değil, ama eğer gerçekten ihtiyacınız olan bir liste var içine alınması filter() çağrı list() kurucu.
  • Lispy bu aromalı *yapıları biraz yabancı Python iş olarak kabul edilecektir. Etrafta 2005, Guido was even talking about dropping filter - birlikte arkadaşları map reduce (onlar henüz gitmedin ama reduce taşındı içine functools modül, hangi değer bir bak istersen high order functions).

4) Matematiksel stili:

List comprehensions PEP 202 sürüm 2.0 tanıtıldı Python listesinde manipülasyon için tercih edilen stil oldu. Sanırım bunun mantığını Liste üreteçleri map() ve ya iç içe döngüler filter() ve/şu anda kullanılan durumlarda listeleri oluşturmak için daha kısa bir yol sağlar.

cleaned_list = [ x for x in some_list if x is not thing ]

Jeneratör ifadeler PEP 289 sürüm 2.4 tanıtıldı. Bir jeneratör ifade için daha iyi durumlarda değilsin gerçekten ihtiyacınız (veya istediğiniz) bir tam listesini hazırladık bellek - sadece istediğiniz üzerinde yineleme unsurları birer birer. Eğer tek liste üzerinden yineleme varsa, lazy evaluated listesi bir anlama jeneratör gibi bir ifade sanırım

for item in (x for x in some_list if x is not thing):
    do_your_thing_with(item)

Notlar

  1. eşitsizlik operatörüis not yerine != (the difference is important) kullanmak isteyebilirsiniz
  2. yöntemleri listenin bir kopyasını ima eleştirenler için: genel kanının aksine, jeneratör ifadeleri her zaman liste üreteçleri daha verimli değil - önce profili lütfen şikayet

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • apenney888

    apenney888

    27 EKİM 2010
  • booba1234

    booba1234

    22 Temmuz 2006
  • talkandroid

    talkandroid

    27 Mayıs 2010