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.