Search code examples
pythonpython-3.xlistcomparisonellipsis

Comparing Lists with Ellipsis in Python


Is there any way to compare lists that reference themselves in Python? You can see what I've tried below:

In[65]:  b
Out[65]: [[...]]

In[66]:  a
Out[66]: [[[[...]]]]

In[67]:  a==b

Traceback (most recent call last):

  File "<ipython-input-67-67c639108cf0>", line 1, in <module>
    a==b

RecursionError: maximum recursion depth exceeded in comparison

I can understand that it cannot keep going into the list forever, but is there still a way to compare lists that have Ellipsis?

[EDIT]:

How a was created:

a=[]
a.append(a)
a=[[[a]]]

How b was created:

b=[]
b.append(b)
b=[b]

Solution

  • Using all and a generator based on list comprehension we can achieve a compare function that works on every case I could figure out:

    def compare(list1: list, list2: list, root1=None, root2=None):
        """Compare recursively nested lists."""
        root1, root2 = (root1, root2) if root1 and root2 else (list1, list2)
        return len(list1) == len(list2) and all(
            ((a, b) == (root1, root2) or a == b)
            and compare(list1[i + 1:], list2[i + 1:], root1, root2)
            for i, (a, b) in enumerate(zip(list1, list2)))
    

    Examples

    For comprehensibility sake I'll write the lists as they are represented when printed instead that building them constantly with appends.

    a, b = ([[...]], [[...]])
    compare(a, b)
    >>> True
    
    a, b = ([[...], 2], [[...]])
    compare(a, b)
    >>> False
    
    a, b = ([2, [...], 2], [[...]])
    compare(a, b)
    >>> False
    
    a, b = ([2, [...], 2], [2, [...], 2])
    compare(a, b)
    >>> True
    
    a, b = ([2, [...], [2]], [2, [...], [3]])
    compare(a, b)
    >>> False
    

    If you'd like for me to test and add more cases I'll happily do it.