Mengapa kode tumbuh daftar iteratif ini memberikan IndexError: daftar indeks tugas di luar jangkauan?


194

Silakan pertimbangkan kode berikut:

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

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

print j

Output (Python 2.6.6 pada Win 7 32-bit) adalah:

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

Saya kira itu adalah sesuatu yang sederhana yang tidak saya mengerti. Bisakah seseorang membersihkannya?


7
appendadalah solusi yang tepat untuk kasus penggunaan Anda, namun ada metode penyisipan pada daftar python yang dapat menyisipkan langsung ke posisi ke-i dalam daftar. j.insert(k, l)
— opensourcegeek

Bolehkah saya bertanya, mengapa solusi OP tidak bekerja? Mengapa menggunakan append?
— Helen

Jawaban:


318

jadalah daftar kosong, tetapi Anda mencoba menulis ke elemen [0]di iterasi pertama, yang belum ada.

Coba yang berikut ini sebagai gantinya, untuk menambahkan elemen baru ke akhir daftar:

for l in i:
    j.append(l)

Tentu saja, Anda tidak akan pernah melakukan ini dalam praktik jika yang Anda inginkan adalah menyalin daftar yang ada. Anda baru saja melakukannya:

j = list(i)

Sebagai alternatif, jika Anda ingin menggunakan daftar Python seperti array dalam bahasa lain, maka Anda bisa membuat daftar sebelumnya dengan elemen-elemennya diatur ke nilai nol ( Nonedalam contoh di bawah), dan kemudian, menimpa nilai di posisi tertentu:

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

Yang perlu disadari adalah bahwa suatu listobjek tidak akan memungkinkan Anda untuk menetapkan nilai pada indeks yang tidak ada.


2
OK, terima kasih banyak. Saya tidak tahu yang mana yang harus dipuji karena ada tiga jawaban yang hampir sama. Ini yang paling deskriptif menurut saya. Cheers
— Vladan

Saya dapat melihat bahwa ini bisa sangat membingungkan bagi mereka yang datang dari bahasa lain seperti PHP atau C. j adalah jenis daftar, bukan array. Dengan tipe daftar, saya tidak berpikir ini bisa disubkripsikan. Sangat membingungkan jika berasal dari bahasa lain.
— Nguai al

@Nguaial Jenis daftar dapat disubkripsikan, tetapi Anda hanya dapat mengakses elemen yang sudah ada - Anda tidak dapat membuat elemen dengan mencoba menulis ke indeks yang berada di luar jangkauan. j [0] = "foo" akan berfungsi jika daftar sudah memiliki setidaknya satu elemen.
— Steve Mayne

52

Pilihan Anda yang lain adalah menginisialisasi j:

j = [None] * len(i)

3
Anda ingin menggunakan len (i) daripada maks.
— Steve Mayne

25

Lakukan j.append(l)alih-alih j[k] = ldan hindari ksama sekali.


2
Cara yang lebih pendek (lebih Pythonic?) Mungkinj+=[l]
— Oleh Prypin

2
@BlaXpirit: Saya pikir itu akan membebani pengumpul sampah.
— khachik

2
@BalXpirit: Mengingat bahwa hanya menyimpan beberapa karakter (terutama karena Anda perlu menambahkan spasi agar dapat diterima) dan itu .appendjauh lebih umum (mungkin karena suatu alasan - saya pikir ini sedikit lebih mudah untuk dipahami), tidak terlalu unggul dengan cara apapun. (Sunting @khachik: Tidak, +=modifikasi di tempat)

15

Anda juga bisa menggunakan pemahaman daftar:

j = [l for l in i]

atau buat salinannya menggunakan pernyataan:

j = i[:]

konstruksi kedua itu rapi
— javadba

2
Jika satu-satunya tujuan adalah menyalin daftar, Anda bisa mengatakan j = daftar (i) Saya pikir pertanyaannya lebih tentang perilaku daftar, daripada secara khusus membutuhkan cara untuk menyalin elemen.
— Steve Mayne

10
j.append(l)

Juga hindari menggunakan huruf kecil "L's" karena mudah bagi mereka untuk menjadi bingung dengan 1's


7

Saya pikir metode memasukkan Python adalah apa yang Anda cari:

Elemen sisipan x pada posisi i. list.insert (i, x)

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

array.insert(1,20)

print(array)

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

1
Tidak ada gunanya menggunakan insertkapan appenddisediakan khusus untuk tujuan ini.
— holdenweb

Pada satu titik informasi, kode Anda sebenarnya dicetak [1, 20, 2, 3, 4, 5].
— holdenweb

Anda menyisipkan pada indeks 1, menggeser indeks 1 dan seterusnya. Nilai yang dimasukkan tidak berakhir pada indeks 2. Iist.insert () hanya benar-benar diperlukan ketika Anda tidak ingin menambahkan item di akhir daftar; pertanyaan di sini tidak persis seperti itu sehingga list.append () lebih disukai.
— Martijn Pieters

Sebenarnya mengapa saya menjawab pertanyaan ini seperti itu saya juga terkejut: D Tidak tahu apa yang saya pikirkan :) Ini persis "list.append ()" yang merupakan jawaban yang diterima. Saya pikir itu membantu orang atau memberikan ide untuk memecahkan masalah mereka sehingga mendapat 5 hit.
— Mehmet Kagan Kayaalp

5

Anda bisa menggunakan kamus (mirip dengan array asosiatif) untuk j

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

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

print j

akan dicetak:

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

Untuk indeks berturut-turut mulai dari 0 pemetaan biasanya struktur data yang salah , terutama ketika pemetaan tidak memiliki pengirisan atau pembalikan karena mereka tidak dimaksudkan untuk menyampaikan urutan tertentu.
— Martijn Pieters

2

Satu lagi cara:

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

Dalam hal ini jakan menjadi array yang numpy


0

Mungkin Anda perlu memperpanjang ()

i=[1,3,5,7]
j=[]
j.extend(i)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.