列表中的省略号[…]是什么意思?


196

我在玩python。我在IDLE中使用了以下代码:

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

输出为:

[1, [...], 2]

这是[…]什么 有趣的是,我现在可以将其用作无穷大列表的列表,即

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

我可以根据需要编写以上内容,并且仍然可以使用。

编辑:

  • 它在内存中如何表示?
  • 有什么用?在某些情况下有用的示例可能会有所帮助。
  • 官方文档的任何链接将非常有用。

仍在寻找EDIT的第一和第三列表元素的答案。
Aseem Bansal

7
一个更简单的例子是p = [1]; p[0] = p
arshajii

6
我认为这与Python中列表中的[…](省略号)什么重复,尽管这个问题的答案更好。
Martin Thoma 2013年

1
Dreampie很聪明`>>> p [1:1] = [p] >>> p 3:3:[1,<ID为3074777548>的列表上的递归>,2] >>>`提供准确的详细信息
Rahul Gautam

@RahulGautam没有得到这个p 3: [1, <Recursion on list with id=3074777548>, 2]。你跑了什么?
Aseem Bansal

Answers:


112

这意味着您创建了一个嵌套在其内部的无限列表,该列表无法打印。p包含p其中包含p...,依此类推。这种[...]记法是一种让您知道这一点并告知它无法表示的方式!看看@ 6502的答案,可以看到一张很好的图片,显示正在发生的事情。

现在,关于编辑后的三个新项目:

  • 这个答案似乎涵盖了它
  • Ignacio的链接描述了一些可能的用途
  • 与编程语言相比,这更是数据结构设计的主题,因此不太可能在Python的官方文档中找到任何参考。

那会占用无限内存吗?我知道这不可能。它如何表示及其用途?
Aseem Bansal

21
@Zel:列表元素是引用。第二个元素是对列表本身的引用。
伊格纳西奥·巴斯克斯

2
Python将其标识为引用的无限循环,因此决定将其简化,这并不是真正的无限。不,这不是真的有用,除了一个思想实验:)
奥斯卡·洛佩斯

2
无限递归结构有一些用途。但是数量不多。
伊格纳西奥·巴斯克斯

@ IgnacioVazquez-Abrams一些示例将很有用。
Aseem Bansal

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由1和2​​交替组成。
pascalhein13年

2
@csharpler:当然,您可以通过分析内容来区分两者,但是它们以相同的表示形式打印。而是使用Common Lisp格式,它们是#(1 #1=#(2 #1# 3))for x#1=#(1 #(2 #1# 3))for y
6502,

5
@BurhanKhalid:第一个是inkscape,第二个是gimpscape(因为我丢掉了svg)
6502年

1
@csharpler:您无法在Python中创建“无限列表”,因为列表确实是可调整大小的数组,而不是链接列表。可以使用来创建Common Lisp中的“无限列表” #1=(1 . #1#)
6502

1
+如果您想像这样绘制acsii图表,请尝试:Asiiflow
Grijesh Chauhan

23

对于“它有什么用”这个问题,这是一个具体的例子。

图归约是有时用来解释计算机语言的一种评估策略。这是用于懒惰评估(尤其是功能语言)的常见策略。

起点是构建一个表示程序将执行的“步骤”顺序的图形。根据在该程序中使用的控制结构,这可能会导致一个循环图(因为该程序包含了某种“永远”循环-或使用递归,其“深度”将在被称为评估时间,而不是在graph-创建时间)...

为了表示这种图,您需要无限的 “数据结构”(有时称为递归数据结构),就像您注意到的那样。通常,虽然有些复杂。

如果您对该主题感兴趣,这里(除其他外)有关于该主题的讲座: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(或abc为此事),你会看到它充满了{...},因为任何两个角指的是回对方。


更简单的字典示例:a = {}; a['a'] = a; print a['a']['a']['a']
user650654 2013年

对我来说,它不是“ ...”,而是显示“ <对具有id = ___>的字典进行递归”
Solomon Ucko '16

@SolomonUcko您可能正在使用IPython,它会自动使用pprint打印内容。如果键入%pprint以关闭漂亮打印,它将显示...
nmclean '16

4

据我了解,这是定点的示例

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

我还无法理解这一点。试图运行这些命令,但是有错误。
Aseem Bansal

@Zel:好吧,您必须在它之前添加OPs代码,以便声明p。
Inkane

1
@Zel:好吧,我不确定它对我自己有多大帮助,但是Firegun说p(因此p [1]表示为[...])是函数f的一个固定点。恕我直言,这是“什么是[...]?”这个问题的可能答案。在这种情况下。
Inkane 2013年

1
我遇到了同样的错误问题,因为在尝试了p = [1]; p[0] = p需要f = lambda x:x[0]工作的简单示例之后,我尝试了该示例。这是一个修复点的示例,但我还无法了解知道这一点的用处。固定点的实际价值是以递归或迭代的方式从其他某个点得出的。如果可能的话,显示如何使用原始问题的列表结构创建Y组合器的示例将很有帮助。
dansalmo 2013年

1
q = lambda: q使无限调用的lambda
whackamadoodle3000 '18

-2

该特殊对象的名称是省略号。我猜想它是在Python解释器/ VM中作为单例对象实现的-类似于无-是各种各样的标记。如您所见,这是Python自己表示列表引用的一种方式。


奇怪的是,似乎没有办法直接实例化Ellipsis对象。例如,该名称不会通过“内置”界面公开。因此,您可以在某些错误(引发异常)中看到对该术语的引用,例如,如果您尝试使用省略号作为索引来提取项目。但是您可以说:el = Ellipsis()或类似的东西(我发现)。
Jim Dennis 2013年

9
实际上,这与Ellipsis对象无关。它只是文字字符串“ [...]”,在打印列表期间检测到循环时将打印该文字字符串。参见代码:hg.python.org/cpython/file/84d6c1c0665e/Objects/…–
杰里米·夏普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.