How to efficiently compare two unordered lists (not sets) in Python?

前端 未结 10 1108
刺人心
刺人心 2020-11-22 15:00
a = [1, 2, 3, 1, 2, 3]
b = [3, 2, 1, 3, 2, 1]

a & b should be considered equal, because they have exactly the same elements, only in different

相关标签:
10条回答
  • 2020-11-22 15:48

    O(n): The Counter() method is best (if your objects are hashable):

    def compare(s, t):
        return Counter(s) == Counter(t)
    

    O(n log n): The sorted() method is next best (if your objects are orderable):

    def compare(s, t):
        return sorted(s) == sorted(t)
    

    O(n * n): If the objects are neither hashable, nor orderable, you can use equality:

    def compare(s, t):
        t = list(t)   # make a mutable copy
        try:
            for elem in s:
                t.remove(elem)
        except ValueError:
            return False
        return not t
    
    0 讨论(0)
  • 2020-11-22 15:48

    Using the unittest module gives you a clean and standard approach.

    import unittest
    
    test_object = unittest.TestCase()
    test_object.assertCountEqual(a, b)
    
    0 讨论(0)
  • 2020-11-22 15:53

    If you know the items are always hashable, you can use a Counter() which is O(n)
    If you know the items are always sortable, you can use sorted() which is O(n log n)

    In the general case you can't rely on being able to sort, or has the elements, so you need a fallback like this, which is unfortunately O(n^2)

    len(a)==len(b) and all(a.count(i)==b.count(i) for i in a)
    
    0 讨论(0)
  • 2020-11-22 15:54

    You can sort both:

    sorted(a) == sorted(b)
    

    A counting sort could also be more efficient (but it requires the object to be hashable).

    >>> from collections import Counter
    >>> a = [1, 2, 3, 1, 2, 3]
    >>> b = [3, 2, 1, 3, 2, 1]
    >>> print (Counter(a) == Counter(b))
    True
    
    0 讨论(0)
提交回复
热议问题