在Python中混淆列表:它是什么?

Dem*_*med 17 python recursion list recursive-datastructures

所以我用Python写了一个简单的二叉树,遇到了[...]

我不相信这与Ellipsis对象有关,它似乎与无限循环有关(由于Python的浅拷贝?).这个无限循环的来源以及为什么它在被访问时扩展时不会被扩展是我完全迷失的东西

>>> a
[[[[[], [], 8, 3], [[], [], 3, 2], 6, 3], [], 1, 4], [[], [], -4, 2], 0, 0]
>>> Keys(a)#With a+b
[0, 1, 6, 8, 3, -4]
>>> Keys(a)#With [a,b]
[8, [...], [...], 3, [...], [...], 6, [...], [...], 1, [...], [...], -4, [...], [...], 0, [...], [...]]
>>> Keys(a)[1]#??
[8, [...], [...], 3, [...], [...], 6, [...], [...], 1, [...], [...], -4, [...], [...], 0, [...], [...], 8, [...], [...], 3, [...], [...], 6, [...], [...], 1, [...], [...], -4, [...], [...], 0, [...], [...]]
Run Code Online (Sandbox Code Playgroud)

版本使用+ b

def Keys(x,y=[]):
    if len(x):y+=[x[2]]+Keys(x[0],y)+Keys(x[1],y)#Though it seems I was using y=y[:]+, this actually outputs an ugly mess
    return y
Run Code Online (Sandbox Code Playgroud)

使用[a,b]的版本

def Keys(x,y=[]):
    if len(x):y+=[x[2],Keys(x[0],y),Keys(x[1],y)]
    return y
Run Code Online (Sandbox Code Playgroud)

那究竟是什么[...]?

CAd*_*ker 25

如果您的圆形结构中有一个指向自身的列表,也会出现这种情况.像这样:

>>> a = [1,2]
>>> a.append(a)
>>> a
[1, 2, [...]]
>>> 
Run Code Online (Sandbox Code Playgroud)

由于python无法打印出结构(它将是一个无限循环),因此它使用省略号来显示结构中存在递归.


我不太确定问题是发生了什么或如何解决它,但我会尝试纠正上面的功能.

在它们中,您首先进行两次递归调用,将数据添加到列表中y,然后再将AGAIN附加到返回的数据中y.这意味着结果中将多次出现相同的数据.

要么只是收集所有数据而不添加任何数据y,例如

return [x[2]]+keys(x[0])+keys(x[1])
Run Code Online (Sandbox Code Playgroud)

或者只是在电话中添加附加内容

y += [x[2]]
keys(x[0], y) #Add left children to y...
keys(x[1], y) #Add right children to y...
return y
Run Code Online (Sandbox Code Playgroud)

(当然,这两个片段都需要处理空列表等)

@Abgan还注意到你真的不想y=[]在初始化器中.


Abg*_*gan 6

我相信,你的'树'包含自己,因此它包含周期.

试试这段代码:

   a = [1,2,3,4]
   print a
   a.append(a)
   print a

第一个打印输出:

  [1,2,3,4]

而第二个:

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

原因是使用

 def Keys(x,y=[]):
 
这是错误和邪恶的.List是一个可变对象,当用作默认参数时,它在函数调用之间保留.所以每个y + ="anything"操作都会添加到同一个列表中(在所有函数调用中,因为函数是递归的...)


有关作为函数默认值传递的可变对象的更多详细信息,请参阅EffbotDevshed.


Ned*_*der 5

我不明白你上面的代码,但我认为是Python解释器跳过无限的数据结构.例如:

>>> a = [0, 1]
>>> a[0] = a
>>> a
[[...], 1]
Run Code Online (Sandbox Code Playgroud)

看起来您的树结构正在变得循环.

关于切片对象的答案不是重点.


Jar*_*rey 2

编辑:如上所述,这不是省略号对象,而是循环列表的结果。我就在这里抢先一步了。如果您在某些实际代码而不是输出中找到省略号,那么了解省略号对象是很好的后备知识。


Python 中的 Ellipsis 对象用于扩展切片表示法。当前的 Python 核心库中未使用它,但开发人员可以在自己的库中定义它。例如,NumPy(或 SciPy)使用它作为其数组对象的一部分。您需要查看 tree() 的文档才能准确了解省略号在此对象中的行为。

来自Python文档

3.11.8 省略号对象

该对象由扩展切片表示法使用(请参阅 Python 参考手册)。它不支持任何特殊操作。仅有一个省略号对象,名为 Ellipsis(内置名称)。

它被写为省略号。