2010-07-04 36 views
25

Bir for döngüsü kullanarak listedeki öğeleri değiştirmeye çalışıyorum ancak bir hata alıyorum (aşağıya bakın). Örnek kod:Döngüdeki liste öğelerinin değiştirilmesi (python)

#!/usr/bin/env python 
# *-* coding: utf8 *-* 

data = [] 
data.append("some") 
data.append("example") 
data.append("data") 
data.append("here") 

for item in data: 
    data[item] = "everything" 

Hata:

Traceback (most recent call last): 
    File "./testy.py", line 11, in <module> 
    data[item] = "everything" 
TypeError: list indices must be integers, not str 

bu sorunu çözmek için herhangi bir yolu var mı?

cevap

57

yerine bu deneyin:

for i in xrange(len(data)): 
    data[i] = "everything" 

Yaşadığınız temel sorun data bir liste olmak üzere data[i] yazarken, i ihtiyaçlar bir tamsayı, listeye bir sayısal endeks olmak olmasıdır. Ama döngüde

for item in data 

item listesinde bulunuyor fiili şey, yani bir dize değil, bir şey sayısal endeksidir. xrange, listedeki değerler yerine sayı üreten bir yineleyicidir, böylece bunu kullanabilirsiniz.

Alternatif böylece tüm yapmanız gereken endeksi alıp öğe hakkında unutmak, enumerate fonksiyon size formun (index, item) ait küpe üzerinde bir yineleyici verir

for i, _ in enumerate(data): 
    data[i] = "everything" 

olurdu. Ben bir yol veya diğer (enumerate veya xrange) önemli ölçüde daha hızlı ya da daha iyi olacağından emin değilim, çünkü liste bir değişken içinde bir uzunluğunu saklamak, böylece liste elemanları saymadan hızlı bir şekilde erişilebildiğini düşünüyorum.

for i, item in enumerate(data): 
    data[i] = func(item) 

Bu tür: Yeni liste değerini hesaplamak için eski liste değeri gerekirse Python listesinde eleman aramak yapmamak çünkü

Ancak, enumerate yolu muhtemelen biraz daha hızlı olacak bunu yaptığınızda

data = [func(item) for item in data] 

, Python yüzden, data her öğe geçmesi buna fonksiyonunu uygulamak ve otomatik sonuçlarından yeni bir liste oluşturmak olacaktır: şeyin daha iyi olsa liste anlama, olarak ifade edilir y func(item) sonucunu listeye doğru yere koyma konusunda endişelenmenize gerek yok. Asıl örneğiniz aslında

+0

Biraz garip (veya geçici çözümü) görünüyor, ama düzgün çalışır. Ben geçersiz öğeler (liste) kimliğine verilmelidir bilmiyordum. Teşekkürler. –

+4

@sigo: bu aslında bir çözüm değil, bu tür bir görev yapmak için% 100 doğru ve çok normal bir yoldur (ancak liste kavramaları hakkında söylediğime dikkat edin). –

+2

Bu özel durumda, liste kavraması daha hızlı "data = [" everything "] * len (data)' ile değiştirilebilir. – EOL

5

İadeler tamsayı indeksi, i. e. örneğinizde data[1] == 'example'. Bu nedenle Python, bir dizeyi arama olarak kullanırken şikayet ediyor.

data[data.index("some")] = "something else" 

Ama sadece üzerlerine döngü istiyorsanız David önerildiği gibi, enumerate() kullanın:

onun değerine göre bir listede bir öğe bulmak istiyorsanız, data.index("value") kullanabilirsiniz. Tamsayılar kullanılarak bir listenin indekslenmesi

0

verimsiz olabilir. Python, altta yatan işaretçilerle bağlantılı tabloyu kullanarak liste öğelerini depolar.Bu durumda, belirli bir öğeyi bulmak için, python i-inci öğeye kadar listeyi geçmelidir.

Böyle biçimini kullanarak verimli olabileceği ileri sürülmektedir: bir [:] = [x * x for x]

İlgili konular