Що означають еліпсиси […] у списку?


196

Я грав у пітоні. Я використовував такий код в IDLE:

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

Вихід був:

[1, [...], 2]

Що це […]? Цікаво, що я міг би зараз використовувати це як список списку до нескінченності, тобто

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

Я міг написати вище, доки захотів, і все одно буде працювати.

Редагувати:

  • Як це представлено в пам'яті?
  • У чому його використання? Приклади деяких випадків, коли це корисно, були б корисними.
  • Будь-яке посилання на офіційну документацію було б дуже корисним.

Ще шукаю відповіді на елемент 1-го та 3-го списку EDIT.
Асеем Бансал

7
Більш простим прикладом може бути p = [1]; p[0] = p.
Аршаджій

6
Я думаю, що це дублікат того, що означає […] (еліпсис) у списку на Python? , хоча питання (та відповіді) краще в цьому питанні.
Мартін Тома

1
Dreampie розумний `>>> p [1: 1] = [p] >>> p 3: [1, <Рекурсія у списку з id = 3074777548>, 2] >>>` надайте точну деталь
Рахул Гаутам

@RahulGautam Не отримав цього p 3: [1, <Recursion on list with id=3074777548>, 2]. Що ти бігав?
Асеем Бансал

Відповіді:


112

Це означає, що ви створили нескінченний список, вкладений всередині себе, який неможливо роздрукувати. pмістить pякий містить p... і так далі. [...]Нотація є спосіб , щоб ви знали це, і повідомити , що він не може бути представлений! Подивіться на відповідь @ 6502, щоб побачити приємну картину, що показує, що відбувається.

Тепер щодо трьох нових елементів після редагування:

  • Ця відповідь, здається, охоплює це
  • Посилання Ігнасіо описує деякі можливі варіанти використання
  • Це скоріше тема дизайну структури даних, ніж мови програмування, тому навряд чи будь-яке посилання знайдеться в офіційній документації Python

Так це забирає невід'ємну пам'ять? Я знаю, що це неможливо. Як він представлений і в чому його використання?
Асеем Бансал

21
@ Zel: елементи списку - це посилання. Другий елемент - це посилання на сам список.
Ігнасіо Васкес-Абрамс

2
Python ідентифікував це як нескінченну цикл посилань, тому вирішив скоротити його, він насправді не нескінченний. І ні, це не дуже корисно, окрім продуманого експерименту :)
Óscar López

2
Існує ... кілька застосувань для нескінченно рекурсивних структур. Але не багато.
Ігнасіо Васкес-Абрамс

@ IgnacioVazquez-Abrams Деякі приклади були б корисні.
Асеем Бансал

316

Це те, що створено вашим кодом

введіть тут опис зображення

Це список, де перший і останній елементи вказують на два числа (1 і 2) і де середній елемент вказує на сам список.

У Common Lisp при включенні друку кругових структур такий об’єкт буде надруковано як

#1=#(1 #1# 2)

що означає, що існує об'єкт (позначений 1 с #1=), який є вектором з трьома елементами, другий - сам об'єкт (зворотний посилання #1#).

В Python замість цього ви просто отримуєте інформацію про те, що структура є круговою [...].

У цьому конкретному випадку опис не є неоднозначним (він зворотно вказує на список, але є лише один список, тому він повинен бути таким). В інших випадках може бути як би неоднозначно ... наприклад в

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

зворотна посилання може вказувати або на зовнішній, або на внутрішній список. Ці дві різні структури, надруковані однаково, можна створити за допомогою

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

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

print(x)
print(y)

і вони будуть в пам'яті як

введіть тут опис зображення


Ви можете знайти такий вміст [1, [2, [...], 3]]: x[1] = [2, [...], 3]і y[1] = [2, 1, [...]], 3]. Це означає, що x складається з 1, а потім повторюється 2s, тоді як y складається з чергування 1s і 2s.
pascalhein

2
@csharpler: звичайно, ви можете їх розрізнити, проаналізувавши вміст, однак вони друкуються з однаковим поданням. У форматі Common Lisp замість цього вони були б #(1 #1=#(2 #1# 3))для xі #1=#(1 #(2 #1# 3))для y.
6502

5
@BurhanKhalid: inkscape для першого та gimp для другого (тому що я скинув svg)
6502

1
@csharpler: ви не можете створити "нескінченний список" в Python, оскільки списки справді змінюються зміною масивів, а не пов'язаними списками. Замість цього можна створити "нескінченний список" у Common Lisp #1=(1 . #1#).
6502

1
+ якщо ви хочете намалювати acsii-схему на кшталт цієї спроби: Asiiflow
Grijesh Chauhan

23

На питання "В чому його користь", ось конкретний приклад.

Скорочення графіків - це стратегія оцінювання, яка використовується колись для інтерпретації комп'ютерної мови. Це загальна стратегія лінивого оцінювання, особливо функціональних мов.

Початковою точкою є побудова графіка, що представляє послідовність «кроків» програми. Залежно від структур управління, що використовуються в цій програмі, це може призвести до циклічного графіка (оскільки програма містить певний цикл "назавжди" - або використовувати рекурсію, "глибина" якої буде відома під час оцінки , але не в графіку- час створення ) ...

Для того, щоб представити такий графік, вам потрібні нескінченні "структури даних" (колись називаються рекурсивними структурами даних), як та, яку ви помітили. Зазвичай, трохи складніше, хоча.

Якщо вас цікавить ця тема, ось (серед багатьох інших) лекція на цю тему:
http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf


7

Ми робимо це весь час в об'єктно-орієнтованому програмуванні. Якщо будь-які два об’єкти посилаються один на одного, прямо чи опосередковано, вони є обома нескінченно рекурсивними структурами (або обома частинами тієї ж нескінченно-рекурсивної структури, залежно від того, як ви дивитесь на неї). Ось чому ви не бачите цього в чомусь такому примітивному, як список - тому що ми зазвичай краще описуємо концепцію як взаємопов'язані "об'єкти", ніж "нескінченний список".

Ви також можете отримати ...з нескінченно-рекурсивним словником. Скажімо, ви хочете словник кутів трикутника, де кожне значення - це словник інших кутів, з'єднаних з цим кутом. Ви можете налаштувати його так:

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

Тепер , якщо ви друкуєте triangle(або aчи bабо cна те пішло), ви побачите , що він сповнений , {...}бо будь-які два кути мають в виду назад один до одного.


a = {}; a['a'] = a; print a['a']['a']['a']
Простіший

Для мене замість "..." це показує "<Рекурсія на dict з id = ___>"
Соломон Учко

@SolomonUcko Ви, мабуть, використовуєте IPython, який автоматично використовує pprint для друку речей. Якщо ви введете %pprintдля вимкнення симпатичного друку, воно відобразиться ....
nmclean

4

Як я зрозумів, це приклад фіксованої точки

p  = [1, 2]
p[1:1] = [p]
f = lambda x:x[1]
f(p)==p
f(f(p))==p

Я не зміг цього зрозуміти. Спробував запустити ці команди, але є помилки.
Асеем Бансал

@ Zel: Ну, ви повинні додати код OPs перед цим, щоб p було оголошено.
Інкане

1
@ Zel: Ну, я не впевнений, наскільки це мені корисно, але Firegun каже, що p (а отже, p [1], представлений як [...]) - це фіксація функції f. ІМХО, це можлива відповідь на питання "Що таке [...]?" в цьому випадку.
Інкане

1
У мене була така ж проблема з помилками, тому що я спробував цей приклад після спроби більш простого p = [1]; p[0] = pприкладу, який повинен f = lambda x:x[0]працювати. Це приклад чіткої точки, але я ще не зміг зрозуміти, наскільки знаю це корисне. Реальне значення точки фіксації надходить до неї з якоїсь іншої точки рекурсивно або ітеративно. Приклад, який показує, як використовувати структуру списку вихідного питання для створення комбінатора Y, буде корисним, якщо це можливо.
дансальмо

1
q = lambda: qробить нескінченну
дзвінку лямбду

-2

Назва цього спеціального об'єкта - Еліпсис. Я здогадуюсь, що він реалізований як одиночний об’єкт в інтепретераторі Python / VM - щось на зразок None --- дозорний тип. Як ви бачили, Python - це спосіб представляти посилання списку всередині себе.


Як не дивно, мабуть, немає способу безпосередньо встановити об'єкт Еліпсиса. Наприклад, ім'я не відображається через інтерфейс Builtins. Таким чином, ви можете бачити посилання на термін у певних помилках (підвищених винятках), наприклад, якщо ви намагаєтеся витягти елемент, використовуючи еліпсис як індекс. Але ви можете просто сказати: el = Ellipsis () і нічого подібного (що я знайшов).
Джим Денніс

9
Це фактично не має нічого спільного з об’єктом Еліпсиса. Це просто буквальний рядок "[...]", який друкується при виявленні циклу під час друку списку. Дивіться код: hg.python.org/cpython/file/84d6c1c0665e/Objects/…
Джеремі Шарп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.