Apa arti ellipsis [...] dalam daftar?

196

Saya bermain-main dengan python. Saya menggunakan kode berikut di IDLE:

p  = [1, 2]
p[1:1] = [p]
print p

Outputnya adalah:

[1, [...], 2]

Apa ini […]? Menariknya sekarang saya bisa menggunakan ini sebagai daftar daftar hingga tak terbatas yaitu

p[1][1][1]....

Saya bisa menulis di atas selama yang saya inginkan dan itu masih akan berhasil.

EDIT:

  • Bagaimana itu direpresentasikan dalam memori?
  • Apa gunanya Contoh beberapa kasus di mana itu berguna akan sangat membantu.
  • Tautan apa pun ke dokumentasi resmi akan sangat berguna.
Aseem Bansal
sumber
Masih mencari jawaban untuk elemen daftar EDIT 1 dan 3.
Aseem Bansal
7
Contoh yang lebih sederhana adalah p = [1]; p[0] = p.
arshajii
6
Saya pikir ini adalah duplikat dari Apa artinya [...] (sebuah elipsis) dalam daftar di Python? , meskipun pertanyaan (dan jawaban) lebih baik dalam pertanyaan ini.
Martin Thoma
1
Dreampie pintar `>>> p [1: 1] = [p] >>> p 3: [1, <Rekursi dalam daftar dengan id = 3074777548>, 2] >>>` memberikan detail yang tepat
Rahul Gautam
@RahulGautam Tidak mengerti p 3: [1, <Recursion on list with id=3074777548>, 2]. Apa yang kamu jalankan?
Aseem Bansal

Jawaban:

112

Ini berarti bahwa Anda membuat daftar tak terbatas yang bersarang di dalam dirinya sendiri, yang tidak dapat dicetak. pberisi pyang berisi p... dan sebagainya. The [...]notasi adalah cara untuk membiarkan Anda tahu ini, dan untuk menginformasikan bahwa hal itu tidak dapat diwakili! Lihatlah jawaban @ 6502 untuk melihat gambar yang bagus menunjukkan apa yang terjadi.

Sekarang, mengenai tiga item baru setelah Anda edit:

  • Jawaban ini sepertinya menutupinya
  • Tautan Ignacio menjelaskan beberapa kemungkinan penggunaan
  • Ini lebih merupakan topik desain struktur data daripada bahasa pemrograman, jadi tidak mungkin ada referensi yang ditemukan dalam dokumentasi resmi Python
Óscar López
sumber
Jadi, apakah itu mengambil memori yang sangat kecil? Saya tahu itu tidak mungkin. Bagaimana cara merepresentasikan dan apa gunanya?
Aseem Bansal
21
@Zel: Elemen daftar adalah referensi. Elemen kedua adalah referensi ke daftar itu sendiri.
Ignacio Vazquez-Abrams
2
Python mengidentifikasinya sebagai loop referensi tanpa batas, sehingga memutuskan untuk memotongnya pendek, itu tidak benar-benar tak terbatas. Dan tidak, itu tidak benar-benar berguna selain eksperimen pikiran :)
Óscar López
2
Ada ... beberapa kegunaan untuk struktur rekursif tanpa batas. Tapi tidak banyak.
Ignacio Vazquez-Abrams
@ IgnacioVazquez-Abrams Beberapa contoh akan berguna.
Aseem Bansal
316

Inilah yang kode Anda buat

masukkan deskripsi gambar di sini

Ini adalah daftar di mana elemen pertama dan terakhir menunjuk ke dua angka (1 dan 2) dan di mana elemen tengah menunjuk ke daftar itu sendiri.

Dalam Common Lisp ketika mencetak struktur lingkaran diaktifkan, objek seperti itu akan dicetak sebagai

#1=#(1 #1# 2)

artinya ada suatu objek (berlabel 1 dengan #1=) yaitu vektor dengan tiga elemen, yang kedua adalah objek itu sendiri (direferensikan kembali dengan #1#).

Dalam Python, Anda hanya mendapatkan informasi bahwa struktur itu melingkar [...].

Dalam kasus khusus ini deskripsinya tidak ambigu (mundur menunjuk ke daftar tetapi hanya ada satu daftar sehingga harus yang satu). Namun dalam kasus lain mungkin ambigu ... misalnya dalam

[1, [2, [...], 3]]

referensi mundur bisa menunjuk ke luar atau ke daftar dalam. Dua struktur berbeda ini dicetak dengan cara yang sama dapat dibuat dengan

x = [1, [2, 3]]
x[1][1:1] = [x[1]]

y = [1, [2, 3]]
y[1][1:1] = [y]

print(x)
print(y)

dan mereka akan berada dalam memori sebagai

masukkan deskripsi gambar di sini

6502
sumber
Anda dapat menemukan konten [1, [2, [...], 3]]seperti ini: x[1] = [2, [...], 3]dan y[1] = [2, 1, [...]], 3]. Ini berarti bahwa x terdiri dari 1 dan mengulangi 2s, sedangkan y terdiri dari 1s dan 2s yang bergantian.
pascalhein
2
@csharpler: tentu saja Anda dapat membedakan keduanya dengan menganalisis konten, namun keduanya dicetak dengan representasi yang sama. Dalam format Common Lisp sebagai gantinya mereka akan #(1 #1=#(2 #1# 3))untuk xdan #1=#(1 #(2 #1# 3))untuk y.
6502
5
@ BurhanKhalid: inkscape untuk yang pertama dan gimp untuk yang kedua (karena saya membuang svg)
6502
1
@csharpler: Anda tidak dapat membuat "daftar tak terbatas" dengan Python karena daftar memang array yang dapat diubah ukurannya, bukan daftar yang ditautkan. "Daftar tak terbatas" di Common Lisp dapat dibuat dengan #1=(1 . #1#).
6502
1
+ jika Anda ingin menggambar acsii-diagram seperti ini, coba: Asiiflow
Grijesh Chauhan
23

Untuk pertanyaan "Apa gunanya", berikut adalah contoh nyata.

Pengurangan grafik adalah strategi evaluasi yang kadang-kadang digunakan untuk menafsirkan bahasa komputer. Ini adalah strategi umum untuk evaluasi malas, terutama bahasa fungsional.

Titik awalnya adalah membuat grafik yang mewakili urutan "langkah" yang akan diambil oleh program. Bergantung pada struktur kontrol yang digunakan dalam program itu, ini mungkin mengarah ke grafik siklik (karena program mengandung semacam loop "selamanya" - atau menggunakan rekursi yang "dalamnya" akan diketahui pada waktu evaluasi , tetapi tidak pada grafik- waktu pembuatan ) ...

Untuk mewakili grafik seperti itu, Anda memerlukan "struktur data" yang tak terbatas (kadang-kadang disebut struktur data rekursif ), seperti yang Anda perhatikan. Biasanya, sedikit lebih rumit.

Jika Anda tertarik dengan topik itu, berikut adalah (di antara banyak lainnya) kuliah tentang hal itu:
http://undergrad.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf

Sylvain Leroux
sumber
7

Kami melakukan ini sepanjang waktu dalam pemrograman berorientasi objek. Jika ada dua objek yang merujuk satu sama lain, secara langsung atau tidak langsung, keduanya adalah struktur rekursif tak terbatas (atau keduanya bagian dari struktur rekursif tak terbatas yang sama, tergantung pada bagaimana Anda melihatnya). Itu sebabnya Anda tidak melihat ini dalam sesuatu yang primitif seperti daftar - karena kita biasanya lebih baik menggambarkan konsep sebagai "objek" yang saling berhubungan daripada "daftar tak terbatas".

Anda juga bisa mendapatkan ...kamus rekursif tanpa batas. Katakanlah Anda menginginkan kamus sudut-sudut segitiga, di mana setiap nilai adalah kamus sudut-sudut lain yang terhubung ke sudut itu. Anda dapat mengaturnya seperti ini:

a = {}
b = {}
c = {}
triangle = {"a": a, "b": b, "c": c}
a["b"] = b
a["c"] = c
b["a"] = a
b["c"] = c
c["a"] = a
c["b"] = b

Sekarang jika Anda mencetak triangle(atau aatau batau cdalam hal ini), Anda akan melihat itu penuh {...}karena setiap dua sudut mengacu ke belakang satu sama lain.

nmclean
sumber
Contoh kamus sederhana:a = {}; a['a'] = a; print a['a']['a']['a']
user650654
Bagi saya, alih-alih "..." itu menunjukkan "<Rekursi pada dikt dengan id = ___>"
Solomon Ucko
@SolomonUcko Anda mungkin menggunakan IPython yang secara otomatis menggunakan sidik jari untuk mencetak sesuatu. Jika Anda mengetik %pprintuntuk mematikan pencetakan yang cukup, itu akan ditampilkan ....
nmclean
4

Seperti yang saya mengerti, ini adalah contoh titik tetap

p  = [1, 2]
p[1:1] = [p]
f = lambda x:x[1]
f(p)==p
f(f(p))==p
Hanfei Sun
sumber
Saya belum bisa memahami ini. Sudah mencoba menjalankan perintah ini tetapi ada kesalahan.
Aseem Bansal
@ Zel: Nah, Anda harus menambahkan kode OPs sebelum itu sehingga p dinyatakan.
Inkane
1
@ Zel: Yah, saya tidak yakin seberapa membantu saya sendiri, tetapi Firegun mengatakan bahwa p (dan karena itu p [1], diwakili sebagai [...]) adalah titik perbaikan fungsi f. IMHO, ini kemungkinan jawaban dari pertanyaan "Apa itu [...]?" pada kasus ini.
Inkane
1
Saya memiliki masalah kesalahan yang sama karena saya telah mencoba contoh ini setelah mencoba p = [1]; p[0] = pcontoh sederhana yang perlu f = lambda x:x[0]bekerja. Ini adalah contoh titik perbaikan, tetapi saya belum bisa melihat bagaimana mengetahui ini berguna. Nilai sebenarnya dari titik perbaikan tiba di sana dari titik lain secara rekursif atau berulang. Contoh yang menunjukkan bagaimana menggunakan struktur daftar dari pertanyaan asli untuk membuat kombinator Y akan sangat membantu jika memungkinkan.
dansalmo
1
q = lambda: qmembuat lambda yang tak terbatas
whackamadoodle3000
-2

Nama benda spesial itu adalah Ellipsis. Saya kira itu diimplementasikan sebagai objek tunggal di Python intepreter / VM - sesuatu seperti None --- semacam penjaga. Seperti yang telah Anda lihat, ini merupakan cara bagi Python untuk mewakili referensi daftar di dalam dirinya sendiri.

Jim Dennis
sumber
Anehnya sepertinya tidak ada cara untuk secara langsung instantiate objek Ellipsis. Nama tidak terpapar melalui antarmuka Builtins misalnya. Jadi, Anda dapat melihat referensi ke istilah dalam kesalahan tertentu (menimbulkan pengecualian) misalnya jika Anda mencoba mengekstraksi item menggunakan elipsis sebagai indeks. Tapi Anda bisa mengatakan: el = Ellipsis () atau yang seperti itu (yang saya temukan).
Jim Dennis
9
Ini sebenarnya tidak ada hubungannya dengan objek Ellipsis. Itu hanya string literal "[...]", yang dicetak ketika sebuah siklus terdeteksi saat mencetak daftar. Lihat kode: hg.python.org/cpython/file/84d6c1c0665e/Objects/…
Jeremy Sharpe