通过为对象引用打印"[...]",Python意味着什么?

Dyc*_*cey 48 python recursion ellipsis recursive-datastructures

我正在打印一个我认为是列表的值,但我得到的输出是:

[...]
Run Code Online (Sandbox Code Playgroud)

这代表什么?我该如何测试呢?我试过了:

myVar.__repr__() != '[...]'
Run Code Online (Sandbox Code Playgroud)

myVar.__repr_() != Ellipsis
Run Code Online (Sandbox Code Playgroud)

但没有骰子......

这是给出问题的代码的缩减:

def buildPaths(graph, start, end, path=[], totalPaths=[]):
    """
    returns list of all possible paths from start node to the end node
    """
    path = path + [start]
    if start == end:
        return path
    for nextNode in graph.childrenOf(start):
        if nextNode not in path:
            newPath = buildPaths(graph, nextNode, end, path, totalPaths)
            if newPath != []: # test
                totalPaths.append(newPath)
    return totalPaths
Run Code Online (Sandbox Code Playgroud)

totalPaths包含很多所谓的递归列表,但我不明白为什么.我在#test修改了测试以防止这种情况发生.

我也尝试过:

def buildPaths(graph, thisNode, end, path=[], totalPaths=None):
    """
   returns list of all possible paths from start node to the end node
   """
    path = path + [thisNode]
    if thisNode == end:
        return path
    for nextNode in graph.childrenOf(thisNode):
        if nextNode not in path:
            newPath = buildPaths(graph, nextNode, end, path, totalPaths)
            if newPath != None:
                if totalPaths == None:
                    totalPaths = [newPath]
                else:
                    totalPaths.append(newPath)
    return totalPaths
Run Code Online (Sandbox Code Playgroud)

为了显式返回None空路径.

Nol*_*lty 48

它代表了结构中的无限循环.一个例子:

In [1]: l = [1, 2]

In [2]: l[0] = l

In [3]: l
Out[3]: [[...], 2]
Run Code Online (Sandbox Code Playgroud)

l第一个项目本身就是.这是一个递归引用,因此python无法合理地显示其内容.相反它显示[...]

  • @Carcigenicate实际上,GHCi开始显示无限列表没有问题,但它很难完成...... Python类需要repr才能在打印前完成执行. (22认同)

MSe*_*ert 31

根据上下文,它可能有不同的东西:

索引/切片 Ellipsis

我认为它没有为任何python类实现,但它应该代表任意数量的数据结构嵌套(非常需要).例如:a[..., 1]应该返回最里面嵌套结构的所有第二个元素:

>>> import numpy as np
>>> a = np.arange(27).reshape(3,3,3)  # 3dimensional array
>>> a[..., 1]  # this returns a slice through the array in the third dimension
array([[ 1,  4,  7],
       [10, 13, 16],
       [19, 22, 25]])
>>> a[0, ...]  # This returns a slice through the first dimension
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)

并检查这个...你比较它Ellipsis(这是一个单身,所以建议使用is:

>>> ... is Ellipsis
True
>>> Ellipsis in [...]
True
# Another (more or less) equivalent alternative to the previous line:
>>> any(i is Ellipsis for i in [1, ..., 2]) 
True
Run Code Online (Sandbox Code Playgroud)

递归数据结构

[...]输出中看到的另一种情况是序列本身内部是否有序列.这里代表无限深层嵌套序列(不可打印).例如:

>>> alist = ['a', 'b', 'c']
>>> alist[0] = alist
>>> alist
[[...], 'b', 'c']

# Infinite deeply nested so you can use as many leading [0] as you want
>>> alist[0][1] 
'b'
>>> alist[0][0][0][0][0][1] 
'b'
>>> alist[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][1] 
'b'
Run Code Online (Sandbox Code Playgroud)

你甚至可以多次更换它:

>>> alist[2] = alist
>>> alist
[[...], 'b', [...]]
>>> alist[1] = alist
>>> alist
[[...], [...], [...]]
Run Code Online (Sandbox Code Playgroud)

要测试输出中是否有任何此类递归,您需要检查数据结构本身是否也是其中一个元素:

>>> alist in alist
True
>>> any(i is alist for i in alist)
True
Run Code Online (Sandbox Code Playgroud)

获得更有意义的输出的另一种方法是使用pprint.pprint:

>>> import pprint
>>> pprint.pprint(alist)  # Assuming you only replaced the first element:
[<Recursion on list with id=1628861250120>, 'b', 'c']
Run Code Online (Sandbox Code Playgroud)


mha*_*wke 21

如果你的列表包含自引用,那么Python将显示为[...]而不是尝试以递归方式将其打印出来,这将导致一个infinte循环:

>>> l = [1, 2, 3]
>>> print(l)
[1, 2, 3]
>>> l.append(l)
>>> print(l)
[1, 2, 3, [...]]
>>> print(l[-1])        # print the last item of list l
[1, 2, 3, [...]]
>>> print(l[-1][-1])    # print the last item of the last item of list l
[1, 2, 3, [...]]
Run Code Online (Sandbox Code Playgroud)

无限的.

词典也出现了类似的情况:

>>> d = {}
>>> d['key'] = d
>>> print(d)
{'key': {...}}
>>> d['key']
{'key': {...}}
>>> d['key']['key']
{'key': {...}}
Run Code Online (Sandbox Code Playgroud)


Pyt*_*sta 11

它是一个递归引用,因为列表包含它自己.Python不会尝试递归打印这会导致无限循环.

repr检测到这个.因此,如果您查看列表对象的内部表示,您将看到(省略号出现的位置)"在地址*处引用相同的列表对象",其中*是内存中原始列表对象的地址.因此,无限循环.