Dấu chấm lửng [tầm] có nghĩa là gì trong một danh sách?


196

Tôi đã chơi xung quanh trong python. Tôi đã sử dụng mã sau đây trong IDLE:

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

Đầu ra là:

[1, [...], 2]

Đây là cái […]gì Điều thú vị là bây giờ tôi có thể sử dụng nó như một danh sách danh sách lên đến vô tận tức là

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

Tôi có thể viết ở trên miễn là tôi muốn và nó vẫn hoạt động.

BIÊN TẬP:

  • Làm thế nào nó được đại diện trong bộ nhớ?
  • Công dụng của nó là gì? Ví dụ về một số trường hợp hữu ích sẽ hữu ích.
  • Bất kỳ liên kết đến tài liệu chính thức sẽ thực sự hữu ích.

Vẫn đang tìm kiếm câu trả lời cho yếu tố danh sách thứ 1 và thứ 3 của EDIT.
Aseem Bansal

7
Một ví dụ đơn giản hơn sẽ là p = [1]; p[0] = p.
arshajii

6
Tôi nghĩ rằng đây là một bản sao [[]] (dấu chấm lửng) trong danh sách có ý nghĩa gì trong Python? , mặc dù câu hỏi (và câu trả lời) tốt hơn trong câu hỏi này.
Martin Thoma

1
Dreampie rất thông minh `>>> p [1: 1] = [p] >>> p 3: [1, <Đệ quy trong danh sách với id = 3074777548>, 2] >>>` cung cấp chi tiết chính xác
Rahul Gautam

@RahulGautam Không hiểu điều này p 3: [1, <Recursion on list with id=3074777548>, 2]. Bạn đã chạy cái gì?
Aseem Bansal

Câu trả lời:


112

Điều đó có nghĩa là bạn đã tạo một danh sách vô hạn được lồng bên trong chính nó, không thể in được. ppchứa p... và như vậy. Các [...]ký hiệu là một cách để cho bạn biết điều này, và thông báo rằng nó không thể được biểu diễn! Hãy xem câu trả lời của @ 6502 để thấy một bức tranh đẹp cho thấy những gì đang xảy ra.

Bây giờ, liên quan đến ba mục mới sau khi chỉnh sửa của bạn:

  • Câu trả lời này dường như bao gồm nó
  • Liên kết của Ignacio mô tả một số cách sử dụng có thể
  • Đây là một chủ đề về thiết kế cấu trúc dữ liệu hơn là ngôn ngữ lập trình, do đó, không có bất kỳ tài liệu tham khảo nào được tìm thấy trong tài liệu chính thức của Python

Vì vậy, nó là lấy bộ nhớ infinte? Tôi biết điều đó là không thể Nó được thể hiện như thế nào và công dụng của nó là gì?
Aseem Bansal

21
@Zel: Danh sách các yếu tố là tài liệu tham khảo. Phần tử thứ hai là một tham chiếu đến chính danh sách.
Ignacio Vazquez-Abrams

2
Python nó xác định nó là một vòng lặp vô hạn của các tham chiếu, vì vậy nó đã quyết định cắt ngắn nó, nó không thực sự vô hạn. Và không, nó không thực sự hữu ích ngoài một thử nghiệm suy nghĩ :)
Óscar López

2
Có ... một vài cách sử dụng cho các cấu trúc đệ quy vô hạn. Nhưng không nhiều.
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams Một số ví dụ sẽ hữu ích.
Aseem Bansal

316

Đây là những gì mã của bạn đã tạo

nhập mô tả hình ảnh ở đây

Đây là danh sách trong đó các phần tử đầu tiên và cuối cùng trỏ đến hai số (1 và 2) và trong đó phần tử ở giữa đang trỏ vào chính danh sách.

Trong Common Lisp khi in cấu trúc vòng tròn được bật, một đối tượng sẽ được in như

#1=#(1 #1# 2)

nghĩa là có một đối tượng (được gắn nhãn 1 với #1=) là một vectơ có ba phần tử, phần tử thứ hai là chính đối tượng (tham chiếu ngược với #1#).

Trong Python thay vì bạn chỉ cần lấy thông tin mà cấu trúc là hình tròn [...].

Trong trường hợp cụ thể này, mô tả không mơ hồ (nó lạc hậu chỉ vào một danh sách nhưng chỉ có một danh sách nên nó phải là danh sách đó). Tuy nhiên, trong các trường hợp khác có thể mơ hồ ... ví dụ như trong

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

tham chiếu ngược có thể chỉ ra bên ngoài hoặc vào danh sách bên trong. Hai cấu trúc khác nhau được in theo cùng một cách có thể được tạo ra với

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

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

print(x)
print(y)

và họ sẽ ở trong ký ức như

nhập mô tả hình ảnh ở đây


Bạn có thể tìm thấy nội dung [1, [2, [...], 3]]như thế này: x[1] = [2, [...], 3]y[1] = [2, 1, [...]], 3]. Điều này có nghĩa là x bao gồm 1 và sau đó lặp lại 2s, trong khi y bao gồm 1 và 2 xen kẽ.
pascalhein

2
@csharpler: tất nhiên bạn có thể phân biệt hai bằng cách phân tích nội dung, tuy nhiên chúng được in với cùng một đại diện. Trong định dạng Lisp chung thay vì họ sẽ #(1 #1=#(2 #1# 3))cho x#1=#(1 #(2 #1# 3))cho y.
6502

5
@BurhanKhalid: inkscape cho lần đầu tiên và gimp cho lần thứ hai (vì tôi đã ném đi Svg)
6502

1
@csharpler: bạn không thể tạo một "danh sách vô hạn" trong Python vì danh sách thực sự là các mảng có thể thay đổi kích thước, không phải là danh sách được liên kết. Thay vào đó, một "danh sách vô hạn" trong Common Lisp có thể được tạo bằng #1=(1 . #1#).
6502

1
+ nếu bạn muốn vẽ sơ đồ acsii như thế này hãy thử: Asiiflow
Grijesh Chauhan

23

Đối với câu hỏi "Công dụng của nó là gì", đây là một ví dụ cụ thể.

Giảm đồ thị là một chiến lược đánh giá đôi khi được sử dụng để giải thích ngôn ngữ máy tính. Đây là một chiến lược phổ biến để đánh giá lười biếng, đáng chú ý là các ngôn ngữ chức năng.

Điểm khởi đầu là xây dựng một biểu đồ biểu thị chuỗi "các bước" mà chương trình sẽ thực hiện. Tùy thuộc vào các cấu trúc điều khiển được sử dụng trong chương trình đó, điều này có thể dẫn đến biểu đồ tuần hoàn (vì chương trình chứa một loại vòng lặp "mãi mãi" - hoặc sử dụng đệ quy có "độ sâu" sẽ được biết tại thời điểm đánh giá , nhưng không phải tại biểu đồ- thời gian sáng tạo ) ...

Để biểu diễn biểu đồ như vậy, bạn cần "cấu trúc dữ liệu" vô hạn (đôi khi được gọi là cấu trúc dữ liệu đệ quy ), giống như cấu trúc dữ liệu bạn nhận thấy. Thông thường, mặc dù phức tạp hơn một chút.

Nếu bạn quan tâm đến chủ đề đó, thì đây là (trong số nhiều bài khác) một bài giảng về chủ đề đó:
http://undergradiated.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf


7

Chúng tôi làm điều này mọi lúc trong lập trình hướng đối tượng. Nếu bất kỳ hai đối tượng nào đề cập đến nhau, trực tiếp hoặc gián tiếp, chúng đều là các cấu trúc đệ quy vô hạn (hoặc cả hai phần của cùng một cấu trúc đệ quy vô hạn, tùy thuộc vào cách bạn nhìn vào nó). Đó là lý do tại sao bạn không thấy điều này nhiều trong một cái gì đó nguyên thủy như một danh sách - bởi vì chúng ta thường mô tả khái niệm này như là các "đối tượng" được kết nối với nhau hơn là một "danh sách vô hạn".

Bạn cũng có thể nhận được ...với một từ điển đệ quy vô hạn. Giả sử bạn muốn có một từ điển các góc của một hình tam giác, trong đó mỗi giá trị là một từ điển của các góc khác được kết nối với góc đó. Bạn có thể thiết lập nó như thế này:

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

Bây giờ nếu bạn in triangle(hoặc ahoặc bhoặc ccho rằng vấn đề), bạn sẽ thấy nó đầy đủ các {...}vì hai góc nào được đề cập đến sao lưu với nhau.


Ví dụ từ điển đơn giản hơn:a = {}; a['a'] = a; print a['a']['a']['a']
user650654

Đối với tôi, thay vì "...", nó hiển thị "<Recursion on dict with id = ___>"
Solomon Ucko

@SolomonUcko Có lẽ bạn đang sử dụng IPython tự động sử dụng pprint để in mọi thứ. Nếu bạn gõ %pprintđể tắt in đẹp, nó sẽ hiển thị ....
nmclean

4

Theo tôi hiểu, đây là một ví dụ về điểm cố định

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

Tôi đã không thể hiểu điều này. Đã thử chạy các lệnh này nhưng có lỗi.
Aseem Bansal

@Zel: Chà, bạn phải thêm mã OP trước khi nó được khai báo.
Inkane

1
@Zel: Chà, tôi không chắc bản thân nó hữu ích như thế nào, nhưng Firegun nói rằng p (và do đó p [1], được biểu thị là [...]) là một điểm cố định của hàm f. IMHO, đây là câu trả lời có thể có của câu hỏi "[...] là gì?" trong trường hợp này.
Inkane

1
Tôi gặp vấn đề tương tự vì tôi đã thử ví dụ này sau khi thử p = [1]; p[0] = pví dụ đơn giản hơn cần f = lambda x:x[0]làm việc. Đây là một ví dụ về một điểm sửa chữa, nhưng tôi chưa thể biết làm thế nào để biết điều này hữu ích. Giá trị thực của điểm sửa chữa đang đến điểm đó từ một số điểm khác theo cách đệ quy hoặc lặp lại. Một ví dụ cho thấy cách sử dụng cấu trúc danh sách của câu hỏi ban đầu để tạo bộ kết hợp Y sẽ hữu ích nếu có thể.
dansalmo

1
q = lambda: qlàm một lambda vô hạn có thể gọi được
whackamadoodle3000

-2

Tên của vật thể đặc biệt đó là Ellipsis. Tôi đoán rằng nó được triển khai như một đối tượng đơn lẻ trong intepreter / VM của Python - một cái gì đó giống như Không --- một trọng điểm của các loại. Như bạn đã thấy, đó là cách để Python thể hiện tham chiếu của một danh sách trong chính nó.


Điều kỳ lạ là dường như không có cách nào để trực tiếp khởi tạo một đối tượng Ellipsis. Tên không được hiển thị thông qua giao diện Buildins chẳng hạn. Vì vậy, bạn có thể thấy các tham chiếu đến thuật ngữ trong một số lỗi nhất định (ngoại lệ được nêu ra), ví dụ nếu bạn cố trích xuất một mục bằng cách sử dụng dấu chấm lửng làm chỉ mục. Nhưng bạn chỉ có thể nói: el = Ellipsis () hoặc bất cứ điều gì tương tự (mà tôi đã tìm thấy).
Jim Dennis

9
Điều này thực sự không có gì để làm với đối tượng Ellipsis. Đó chỉ là chuỗi ký tự "[...]", được in khi phát hiện một chu kỳ trong khi in danh sách. Xem mã: hg.python.org/cpython/file/84d6c1c0665e/Objects/ trộm
Jeremy Sharpe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.