Co oznacza elipsa […] na liście?

196

Bawiłem się w python. Użyłem następującego kodu w IDLE:

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

Wynik był:

[1, [...], 2]

Co to […]jest Co ciekawe, mógłbym teraz użyć tego jako listy listy do nieskończoności tj

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

Mógłbym napisać powyższe tak długo, jak chciałem i nadal by działało.

EDYTOWAĆ:

  • Jak jest reprezentowany w pamięci?
  • Jakie jest jego zastosowanie? Przydałyby się przykłady niektórych przypadków, w których jest to przydatne.
  • Każdy link do oficjalnej dokumentacji byłby naprawdę przydatny.
Aseem Bansal
źródło
Wciąż szukam odpowiedzi na pierwszy i trzeci element EDIT.
Aseem Bansal,
7
Prostszym przykładem byłoby p = [1]; p[0] = p.
arshajii
6
Myślę, że jest to duplikat tego, co oznacza […] (elipsa) na liście w Pythonie? , chociaż pytanie (i odpowiedzi) jest lepsze w tym pytaniu.
Martin Thoma,
1
Dreampie jest mądry `>>> p [1: 1] = [p] >>> p 3: [1, <Rekurencja na liście o id = 3074777548>, 2] >>>` `podaj dokładne szczegóły
Rahul Gautam
@RahulGautam Nie dostałem tego p 3: [1, <Recursion on list with id=3074777548>, 2]. Co prowadziłeś?
Aseem Bansal,

Odpowiedzi:

112

Oznacza to, że utworzyłeś nieskończoną listę zagnieżdżoną w sobie, której nie można wydrukować. pzawiera pktóry zawiera p... i tak dalej. [...]Notacja jest sposobem, aby poinformować to i poinformować, że nie może być reprezentowane! Spójrz na odpowiedź @ 6502, aby zobaczyć ładne zdjęcie pokazujące, co się dzieje.

Teraz, odnośnie trzech nowych elementów po twojej edycji:

  • Ta odpowiedź wydaje się to obejmować
  • Link Ignacio opisuje niektóre możliwe zastosowania
  • Jest to bardziej temat projektowania struktury danych niż języków programowania, więc jest mało prawdopodobne, aby jakieś odniesienia znajdowały się w oficjalnej dokumentacji Pythona
Óscar López
źródło
Czy zajmuje to nieskończoną pamięć? Wiem, że to niemożliwe. Jak jest reprezentowany i do czego służy?
Aseem Bansal
21
@Zel: Elementy listy są referencjami. Drugi element to odniesienie do samej listy.
Ignacio Vazquez-Abrams,
2
Python zidentyfikował go jako nieskończoną pętlę odniesień, więc postanowił go skrócić, nie jest tak naprawdę nieskończony. I nie, to nie jest tak przydatne poza eksperymentem myślowym :)
Óscar López
2
Istnieje ... kilka zastosowań nieskończenie rekurencyjnych struktur. Ale nie wielu.
Ignacio Vazquez-Abrams,
@ IgnacioVazquez-Abrams Przydatne byłyby niektóre przykłady.
Aseem Bansal
316

To właśnie utworzył Twój kod

wprowadź opis zdjęcia tutaj

Jest to lista, w której pierwszy i ostatni element wskazują dwie liczby (1 i 2), a środkowy element wskazuje samą listę.

W Common Lisp, gdy włączone jest drukowanie struktur okrągłych, taki obiekt byłby drukowany jako

#1=#(1 #1# 2)

co oznacza, że ​​istnieje obiekt (oznaczony 1 za pomocą #1=), który jest wektorem z trzema elementami, drugim jest sam obiekt (z odniesieniem wstecz #1#).

Zamiast tego w Pythonie otrzymujesz informacje, z którymi struktura jest okrągła [...].

W tym konkretnym przypadku opis nie jest dwuznaczny (wskazuje do tyłu na listę, ale istnieje tylko jedna lista, więc musi być ta). W innych przypadkach mogą być jednak niejednoznaczne ... na przykład w

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

odniesienie do tyłu może wskazywać na zewnętrzną lub wewnętrzną listę. Te dwie różne struktury wydrukowane w ten sam sposób można utworzyć za pomocą

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

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

print(x)
print(y)

i będą w pamięci jako

wprowadź opis zdjęcia tutaj

6502
źródło
Możesz znaleźć zawartość [1, [2, [...], 3]]tego: x[1] = [2, [...], 3]a y[1] = [2, 1, [...]], 3]. Oznacza to, że x składa się z 1, a następnie powtarzających się 2s, podczas gdy y składa się z naprzemiennych 1s i 2s.
pascalhein
2
@csharpler: oczywiście można je rozróżnić, analizując zawartość, jednak są one drukowane z tą samą reprezentacją. Zamiast tego w formacie Common Lisp byłyby #(1 #1=#(2 #1# 3))za xi #1=#(1 #(2 #1# 3))za y.
6502
5
@BurhanKhalid: inkscape dla pierwszego i gimp dla drugiego (bo wyrzuciłem svg)
6502
1
@csharpler: w Pythonie nie można utworzyć „nieskończonej listy”, ponieważ listy są rzeczywiście tablicami o zmiennym rozmiarze, a nie listami połączonymi. Zamiast tego można utworzyć „nieskończoną listę” w Common Lisp #1=(1 . #1#).
6502
1
+ jeśli chcesz narysować schemat acsii w następujący sposób
Grijesh Chauhan
23

Na pytanie „Do czego służy”, oto konkretny przykład.

Redukcja wykresów jest strategią oceny używaną kiedyś do interpretacji języka komputerowego. Jest to powszechna strategia leniwej oceny, zwłaszcza języków funkcjonalnych.

Punktem wyjścia jest zbudowanie wykresu przedstawiającego sekwencję „kroków”, które wykona program. W zależności od struktur kontrolnych używanych w tym programie może to prowadzić do cyklicznego wykresu (ponieważ program zawiera pewnego rodzaju „wieczną” pętlę - lub użyć rekurencji, której „głębokość” będzie znana w czasie oceny , ale nie w grafie czas utworzenia ) ...

Aby przedstawić taki wykres, potrzebujesz nieskończonych „struktur danych” (czasami nazywanych rekurencyjnymi strukturami danych), takich jak te, które zauważyłeś. Zwykle jest to jednak trochę bardziej skomplikowane.

Jeśli jesteś zainteresowany tym tematem, oto (między innymi) wykład na ten temat:
http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf

Sylvain Leroux
źródło
7

Robimy to cały czas w programowaniu obiektowym. Jeśli jakieś dwa obiekty odnoszą się do siebie, bezpośrednio lub pośrednio, oba są strukturami nieskończenie rekurencyjnymi (lub obydwoma częściami tej samej nieskończenie rekurencyjnej struktury, w zależności od tego, jak na to patrzysz). Dlatego nie widzisz tak wiele w czymś tak prymitywnym jak lista - ponieważ zwykle lepiej jest opisywać tę koncepcję jako powiązane ze sobą „obiekty” niż „nieskończoną listę”.

Możesz także uzyskać ...z nieskończenie rekurencyjnym słownikiem. Załóżmy, że potrzebujesz słownika narożników trójkąta, gdzie każda wartość jest słownikiem innych narożników połączonych z tym narożnikiem. Możesz to skonfigurować w następujący sposób:

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

Teraz, jeśli wydrukować triangle(lub alub blub cdla tej sprawy), zobaczysz, że to pełne {...}bo jakieś dwa rogi odnosimy się do siebie wzajemnie.

nmclean
źródło
Prostszy przykład słownika:a = {}; a['a'] = a; print a['a']['a']['a']
user650654
Dla mnie zamiast „...” pokazuje się „<Rekurs na dycie o id = ___>”
Solomon Ucko
@ SolomonUcko Prawdopodobnie używasz IPython, który automatycznie używa pprint do drukowania rzeczy. Jeśli wpiszesz, %pprintaby wyłączyć ładne drukowanie, pojawi się ....
nmclean 18.04.16
4

Jak zrozumiałem, jest to przykład punktu stałego

p  = [1, 2]
p[1:1] = [p]
f = lambda x:x[1]
f(p)==p
f(f(p))==p
Hanfei Sun
źródło
Nie byłem w stanie tego zrozumieć. Próbowałem uruchomić te polecenia, ale wystąpiły błędy.
Aseem Bansal
@Zel: Cóż, musisz dodać kod OP przed nim, aby p został zadeklarowany.
Inkane
1
@Zel: Cóż, nie jestem pewien, jak pomocny jest sam, ale Firegun mówi, że p (a zatem p [1], reprezentowane jako [...]) jest stałym punktem funkcji f. IMHO, to możliwa odpowiedź na pytanie „Co to jest [...]?” w tym przypadku.
Inkane
1
Miałem ten sam błąd, ponieważ próbowałem tego przykładu po wypróbowaniu prostszego p = [1]; p[0] = pprzykładu, który musi f = lambda x:x[0]działać. Jest to przykład punktu naprawczego, ale nie byłem jeszcze w stanie zobaczyć, jak wiedza o tym jest przydatna. Rzeczywista wartość punktu stałego dochodzi do niego z innego punktu w sposób rekurencyjny lub iteracyjny. Przykład, który pokazuje, jak użyć struktury listy pierwotnego pytania do utworzenia kombinatora Y, byłby pomocny, jeśli jest to możliwe.
dansalmo
1
q = lambda: qrobi nieskończenie wywoływaną lambda
whackamadoodle3000
-2

Nazwa tego specjalnego obiektu to Ellipsis. Wydaje mi się, że jest zaimplementowany jako obiekt singletonowy w interpreterie / maszynie wirtualnej Pythona - coś w rodzaju None --- swego rodzaju wartownik. Jak widziałeś, jest to sposób, w jaki Python może reprezentować odwołanie do listy w sobie.

Jim Dennis
źródło
Co dziwne, wydaje się, że nie ma możliwości bezpośredniego utworzenia obiektu Ellipsis. Nazwa nie jest ujawniana na przykład przez interfejs wbudowany. Możesz więc zobaczyć odniesienia do tego terminu w niektórych błędach (podniesione wyjątki), na przykład, jeśli próbujesz wyodrębnić element, używając elipsy jako indeksu. Ale możesz po prostu powiedzieć: el = Ellipsis () ani nic takiego (które znalazłem).
Jim Dennis
9
To nie ma nic wspólnego z obiektem Ellipsis. To tylko dosłowny ciąg „[...]”, który jest drukowany po wykryciu cyklu podczas drukowania listy. Zobacz kod: hg.python.org/cpython/file/84d6c1c0665e/Objects/…
Jeremy Sharpe