Bu yinelemeli liste büyüyen kod neden IndexError: liste atama dizinini aralık dışında veriyor?


194

Lütfen aşağıdaki kodu göz önünde bulundurun:

i = [1, 2, 3, 5, 8, 13]
j = []
k = 0

for l in i:
    j[k] = l
    k += 1

print j

Çıktı (Win 7 32 bit'te Python 2.6.6):

> Traceback (most recent call last): 
>     j[k] = l IndexError: list assignment index out of range

Sanırım anlamadığım basit bir şey. Birisi temizleyebilir mi?


7
appendkullanım durumunuz için doğru çözümdür, ancak python listesinde doğrudan listedeki i'ci konuma ekleyebilecek bir ekleme yöntemi vardır. j.insert(k, l)
opensourcegeek

Sorabilir miyim, OP'nin çözümü neden işe yaramaz? Neden append kullanılır?
Helen

Yanıtlar:


317

jboş bir liste, ancak [0]ilk yinelemede henüz var olmayan öğeye yazmaya çalışıyorsunuz .

Listenin sonuna yeni bir öğe eklemek için bunun yerine şunu deneyin:

for l in i:
    j.append(l)

Tabii ki, tek yapmanız gereken mevcut bir listeyi kopyalamak olsaydı bunu pratikte asla yapmazsınız. Sadece yapardınız:

j = list(i)

Alternatif olarak, Python listesini başka dillerde bir dizi gibi kullanmak istiyorsanız, öğeleri null değerine ( Noneaşağıdaki örnekte) ayarlanmış bir listeyi önceden oluşturabilir ve daha sonra belirli konumlardaki değerlerin üzerine yazabilirsiniz:

i = [1, 2, 3, 5, 8, 13]
j = [None] * len(i)
#j == [None, None, None, None, None, None]
k = 0

for l in i:
   j[k] = l
   k += 1

Gerçekleştirilecek şey, bir listnesnenin var olmayan bir dizine bir değer atamanıza izin vermeyeceğidir.


2
Tamam çok teşekkür ederim. Hangisinin övüleceğini bilmiyordum, çünkü neredeyse üç aynı cevap var. Sanırım bu en açıklayıcı. Şerefe
Vladan

Bunun PHP veya C gibi diğer dillerden gelenler için çok kafa karıştırıcı olabileceğini görebiliyorum. J bir dizi değil bir liste türüdür. Liste türü ile bunun abone olabileceğini sanmıyorum. Diğer dillerden geliyorsa çok kafa karıştırıcı.
Nguai al

@Nguaial Liste türü aboneliklidir, ancak yalnızca önceden var olan öğelere erişebilirsiniz; aralık dışındaki bir dizine yazmaya çalışarak öğe oluşturamazsınız. j [0] = "foo" listede zaten en az bir öğe varsa çalışır.
Steve Mayne

52

Diğer seçeneğiniz başlatmaktır j:

j = [None] * len(i)

3
Max yerine len (i) kullanmak istiyorsunuz.
Steve Mayne

25

Bunun j.append(l)yerine yapın j[k] = lve kaçının k.


2
Daha kısa (daha Pythonic?) Bir yol olabilirj+=[l]
Oleh Prypin

2
@BlaXpirit: Çöp toplayıcısına yük getireceğini düşünüyorum.
khachik

2
@BalXpirit: Bunun sadece birkaç karakter kazandırdığı göz önüne alındığında (özellikle kabul edilebilir olması için boşluk eklemeniz gerektiğinden) ve bu .appendçok daha yaygın (belki de bir nedenden ötürü - anlamanın biraz daha kolay olduğunu düşünüyorum), gerçekten üstün değil herhangi bir şekilde. (@Khachik: Hayır, +=yerinde değişiklik yapar)

15

Bir liste kavrayışı da kullanabilirsiniz:

j = [l for l in i]

veya şu ifadeyi kullanarak bir kopyasını oluşturun:

j = i[:]

ikinci inşaat temiz
javadba

2
Tek hedef listeyi kopyalamaksa, basitçe j = list (i) diyebilirim.
Steve Mayne

10
j.append(l)

Ayrıca küçük harf "L" kullanmaktan kaçının çünkü 1'lerle karıştırılmaları kolaydır


7

Bence Python yöntemi eklemek ne arıyorsun:

İ konumuna x elemanını ekler. list.insert (i, x)

array = [1,2,3,4,5]

array.insert(1,20)

print(array)

# prints [1,2,20,3,4,5]

1
Bu amaç için özel olarak insertne zaman appendverildiğini kullanmanın bir anlamı yoktur .
holdenweb

Bir bilgi noktasında, aslında kodunuz yazdırılır [1, 20, 2, 3, 4, 5].
holdenweb

Dizin 1'e, indeksler 1 ve sonrasında yer değiştirerek girdiniz. Girilen değer dizin 2 ile bitmez. Iist.insert () yalnızca öğeyi listenin sonuna eklemek istemediğinizde gerçekten gereklidir; burada soru tam olarak bunu yapar, list.append () tercih edilir.
Martijn Pieters

Aslında neden ben de şaşırdım gibi bu soruya cevap: D Ne düşündüğümü bilmiyorum :) Bu tam olarak "list.append ()" kabul edilen cevaptır. Sanırım insanlara yardımcı oluyor ya da sorunlarını çözmek için bir fikir veriyor, böylece 5 sonuç alıyor.
Mehmet Kagan Kayaalp

5

J için bir sözlük (ilişkilendirilebilir diziye benzer) kullanabilirsiniz

i = [1, 2, 3, 5, 8, 13]
j = {} #initiate as dictionary
k = 0

for l in i:
    j[k] = l
    k += 1

print j

yazdıracak:

{0: 1, 1: 2, 2: 3, 3: 5, 4: 8, 5: 13}

0'dan başlayan ardışık göstergeler için bir eşleme genellikle yanlış veri yapısıdır, özellikle eşlemeler herhangi bir belirli siparişi iletmeleri amaçlanmadığı için dilimleme veya tersine dönmediklerinde .
Martijn Pieters

2

Bir yol daha:

j=i[0]
for k in range(1,len(i)):
    j = numpy.vstack([j,i[k]])

Bu durumda jbir numpy dizisi olacak


0

Belki de uzatmak gerekir ()

i=[1,3,5,7]
j=[]
j.extend(i)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.