I'm printing a value of a what I thought was a list, but the output that I get is:
[...]
What does this represent? How do I test for it? I've tried:
myVar.__repr__() != '[...]'
and
myVar.__repr_() != Ellipsis
but no dice...
Here's a cutdown of the code that's giving the issue:
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
totalPaths contains a LOT of [...] supposedly recursive lists, but I can't see why. I've altered the test at #test to prevent this.
I've also tried:
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
in order to explicitly return None
for empty paths.
A Python program accesses data values through references. A reference is a name that refers to the specific location in memory of a value (object). References take the form of variables, attributes, and items. In Python, a variable or other reference has no intrinsic type.
A link to an object. Object references can be used exactly like the linked objects. The concept of object references becomes clear when assigning the same object to more than one property.
Reference values are hidden in Python. There isn't any explicit user type for storing the reference value. However, you can use a list element (or element in any other suitable container type) as the reference variable, because all containers do store the elements also as references to the target objects.
It represents an infinite loop within the structure. An example:
In [1]: l = [1, 2]
In [2]: l[0] = l
In [3]: l
Out[3]: [[...], 2]
l
's first item is itself. It's a recursive reference, and so python can't reasonably display its contents. Instead it shows [...]
Depending on the context here it could different things:
Ellipsis
I think it's not implemented for any python class but it should represent an arbitary number of data structure nestings (as much needed).
So for example: a[..., 1]
should return all the second elements of the innermost nested structure:
>>> 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]])
and to check for this ...
you compare it to an Ellipsis
(this is a singleton so recommended is using 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
The other case in which you see an [...]
in your output is if you have the sequence inside the sequence itself. Here it stands for an infinite deeply nested sequence (that's not printable). For example:
>>> 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'
You can even replace it several times:
>>> alist[2] = alist
>>> alist
[[...], 'b', [...]]
>>> alist[1] = alist
>>> alist
[[...], [...], [...]]
To test if you have any such recursion in your output you need to check if the data-structure itself is also one of the elements:
>>> alist in alist
True
>>> any(i is alist for i in alist)
True
Another way to get a more meaningful output is using pprint.pprint
:
>>> import pprint
>>> pprint.pprint(alist) # Assuming you only replaced the first element:
[<Recursion on list with id=1628861250120>, 'b', 'c']
If your list contains self references Python will display that as [...]
rather than trying to recursively print it out, which would lead to an infinte loop:
>>> 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, [...]]
ad infinitum.
A similar situation arises with dictionaries:
>>> d = {}
>>> d['key'] = d
>>> print(d)
{'key': {...}}
>>> d['key']
{'key': {...}}
>>> d['key']['key']
{'key': {...}}
It's a recursive reference as your list contains itself. Python doesn't try to recursively print this which would lead to an infinite loop.
repr
detects this. So, if you looked at the internal representation of your list object you would see (where the ellipsis occur) "Reference to the same list object at address *" where * is the address of the original list object in memory. Hence, the infinite loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With