Şimdi yinelemeli bir döngü sırasında listeyi değiştirmenin güvenli olmadığını biliyorum. Ancak, dizelerin bir listesi var ve dizeleri kendileri şerit istiyorum. Değişken değerlerin değiştirilmesi değişiklik olarak kabul edilir mi?
Şimdi yinelemeli bir döngü sırasında listeyi değiştirmenin güvenli olmadığını biliyorum. Ancak, dizelerin bir listesi var ve dizeleri kendileri şerit istiyorum. Değişken değerlerin değiştirilmesi değişiklik olarak kabul edilir mi?
Yanıtlar:
Kötü form olarak kabul edilir. Listeye var olan referansları tutmanız gerekirse, dilim atamasıyla birlikte bir liste kavrayışı kullanın.
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
print byürütüldüğünde, adeğiştirilmek yerine yerinde değiştirilip değiştirilmediğini anlayabilirsiniz . Başka bir olasılık, her print b is aikisinin de hala aynı nesneye atıfta bulunup bulunmadığını görmek olacaktır.
Aşağıdaki döngü yalnızca daha önce görülen öğeleri değiştirdiğinden, kabul edilebilir olarak kabul edilir:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
Hangisi farklı:
a[:] = [s.strip() for s in a]
daha fazla indeksleme işlemi gerektirmesine rağmen, orijinal bir listenin oluşturulmasını ve orijinalin yerini almasını gerektirmez.
Dikkat: Girişleri bu şekilde değiştirebilmenize rağmen list, sorunla karşılaşma şansını riske atmadan öğelerin sayısını değiştiremezsiniz .
İşte ne demek istediğime bir örnek - bir giriş silindiğinde, o noktadan itibaren dizin oluşturma işlemi bozulur:
b = ['a', ' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c '] # WRONG!
(Sonuç yanlıştır, çünkü olması gereken tüm öğeleri silmemiştir.)
Güncelleme
Bu oldukça popüler bir cevap olduğundan, "yerinde" girişleri nasıl etkili bir şekilde silebilirsiniz (bu tam olarak soru olmamasına rağmen):
b = ['a',' b', 'c ', ' d ']
b[:] = [entry for entry in b if entry.strip() == entry]
print(b) # -> ['a'] # CORRECT
for i in a? Bu çok mantıksız, görünüşte diğer dillerden farklı ve kodumda uzun bir süre hata ayıklamak zorunda kalmama neden oldu. Python Tutorial bundan bile bahsetmiyor. Buna bir neden olmalı olsa da?
a[i]ve s) kullanıyorsun? Çok tercih ederim a[i] = a[i].strip().
a[i] = s.strip()sadece bir indeksleme işlemi var.
enumerate(b)her yinelemede bir dizin oluşturma işlemi yapar ve siz de başka bir işlem gerçekleştirirsiniz a[i] =. AFAIK, bu döngüyü döngü yineleme başına yalnızca 1 dizinleme işlemi ile Python'a uygulamak imkansızdır :(
Döngü varyantı için bir tane daha, bana enumerate () ile olandan daha temiz görünüyor:
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
range(len(list))Python'da olduğu gibi bir kod kokusu kullanmayı düşünüyor .
enumerateBir jeneratör olduğu için bir liste oluşturmuyor. Tuples'ın bir listesi, liste boyunca tekrarlanırken birer birer oluşturur. Hangisinin daha yavaş olduğunu söylemenin tek yolu olurdu timeit.
Listeye öğe ekleme / kaldırma işlemini değiştirmediğiniz sürece, bir listeyi tekrarlarken her öğeyi değiştirmek iyidir.
Liste kavrayışını kullanabilirsiniz:
l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]
veya sadece C-stylefor döngüsünü yapın:
for index, item in enumerate(l):
l[index] = item.strip()
Hayır, dizeleri bu şekilde değiştirebilirseniz listenin "içeriğini" değiştiremezsiniz. Ancak Python'da değişmezler. Herhangi bir dize işlemi yeni bir dize döndürür.
Değişken olduğunu bildiğiniz nesnelerin bir listesi varsa, listenin gerçek içeriğini değiştirmediğiniz sürece bunu yapabilirsiniz.
Böylece bir tür harita yapmanız gerekecek. Bir jeneratör ifadesi kullanırsanız, yineleme yaptığınızda [işlem] yapılır ve hafızadan tasarruf edersiniz.
Jemshit Iskenderov ve Ignacio Vazquez-Abrams'ın verdiği cevap gerçekten çok iyi. Bu örnekle daha fazla açıklanabilir:
a) Size iki vektör içeren bir liste verilir;
b) listeden geçmek ve dizilerin her birinin sırasını ters çevirmek istersiniz
Diyelim ki var
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i = i[::-1] # this command does not reverse the string
print([v,b])
Alacaksın
[array([1, 2, 3, 4]), array([3, 4, 6])]
Öte yandan, eğer
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i[:] = i[::-1] # this command reverses the string
print([v,b])
Sonuç
[array([4, 3, 2, 1]), array([6, 4, 3])]
Sorunuzdan hangi dizelerin kaldırılacağına karar verme ölçütlerinin ne olduğu açık değildir, ancak kaldırmak istediğiniz dizelerin bir listesine sahipseniz veya bunları listeleyebiliyorsanız aşağıdakileri yapabilirsiniz:
my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
bu benim dizelerimi ['a', 'c', 'e'] olarak değiştirir
Kısacası, aynı listeyi tekrarlarken listede değişiklik yapmak.
list[:] = ["Modify the list" for each_element in list "Condition Check"]
misal:
list[:] = [list.remove(each_element) for each_element in list if each_element in ["data1", "data2"]]