сравнение содержимого двух списков python [duplicate]

Другим случаем, когда NullReferenceExceptions может случиться, является (неправильное) использование оператора as :

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

Здесь Book и Car являются несовместимыми типами; a Car не может быть преобразован / передан в Book. Когда этот сбой завершается неудачно, as возвращает null. Используя mybook после этого, вы вызываете NullReferenceException.

В общем случае вы должны использовать cast или as, как показано ниже:

Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:

ComicBook cb = (ComicBook)specificBook;

Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as:

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}

87
задан Raymond Hettinger 21 October 2011 в 01:42
поделиться

9 ответов

O (n): лучше всего подходит метод Counter () (если ваши объекты хешируются):

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

O (n log n): лучше всего подходит метод sorted () (если ваши объекты упорядочиваются):

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

O (n * n) : Если объекты не являются ни хешируемыми, ни упорядочиваемыми, вы можете использовать равенство:

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
150
ответ дан CrowbarKZ 25 August 2018 в 06:43
поделиться

https://docs.python.org/3.5/library/unittest.html#unittest.TestCase.assertCountEqual

assertCountEqual (первый, второй, msg = None)

Проверить, что последовательность сначала содержит те же самые элементы, что и вторая, независимо от их порядка. Когда они этого не сделают, появится сообщение об ошибке, в котором перечислены различия между последовательностями.

Дублирующие элементы не игнорируются при сравнении первого и второго. Он проверяет, имеет ли каждый элемент один и тот же счетчик в обеих последовательностях. Эквивалент: assertEqual (счетчик (список (первый)), счетчик (список (второй))), но также работает с последовательностями нераспаковываемых объектов.

Новое в версии 3.2.

или в 2.7: https://docs.python.org/2.7/library/unittest.html#unittest.TestCase.assertItemsEqual

2
ответ дан cleder 25 August 2018 в 06:43
поделиться

Надеюсь, что в вашем случае может работать следующий фрагмент кода: -

if ((len(a) == len(b)) and
   (all(i in a for i in b))):
    print 'True'
else:
    print 'False'

Это гарантирует, что все элементы в обоих списках a & amp; b одинаковы независимо от того, находятся ли они в одном порядке или нет.

Для лучшего понимания см. мой ответ в на этот вопрос

1
ответ дан Community 25 August 2018 в 06:43
поделиться

Если сравнение должно быть выполнено в контексте тестирования, используйте assertCountEqual(a, b) (py>=3.2) и assertItemsEqual(a, b) (2.7<=py<3.2).

Работает и с последовательностями неотображаемых объектов.

2
ответ дан jarekwg 25 August 2018 в 06:43
поделиться

Если вы знаете, что элементы всегда хешируются, вы можете использовать Counter(), который является O (n). Если вы знаете, что элементы всегда сортируемы, вы можете использовать sorted(), который является O (n log n)

В общем случае вы не можете полагаться на возможность сортировки или наличия элементов, поэтому вам нужен такой резерв, который, к сожалению, O (n ^ 2)

len(a)==len(b) and all(a.count(i)==b.count(i) for i in a)
10
ответ дан John La Rooy 25 August 2018 в 06:43
поделиться

Лучший способ сделать это - сортировка списков и их сравнение. (Использование Counter не будет работать с объектами, которые не являются хешируемыми.) Это просто для целых чисел:

sorted(a) == sorted(b)

Это становится немного сложнее с произвольными объектами. Если вам небезразличен идентификатор объекта, то есть, являются ли те же объекты в обоих списках, вы можете использовать функцию id() в качестве ключа сортировки.

sorted(a, key=id) == sorted(b, key==id)

(In Python 2.x вам действительно не нужен параметр key=, потому что вы можете сравнивать любой объект с любым объектом. Порядок произвольный, но стабильный, поэтому он отлично подходит для этой цели, неважно, какой порядок объектов в том числе, что упорядочение одинаково для обоих списков. В Python 3, однако, сравнение объектов разных типов запрещено во многих случаях - например, вы не можете сравнивать строки с целыми числами, поэтому, если у вас будет объекты разных типов, лучше всего использовать идентификатор объекта.)

Если вы хотите сравнить объекты в списке по значению , , с другой стороны, сначала вам нужно определить, что означает «значение» для объектов. Тогда вам понадобится какой-то способ предоставить это как ключ (и для Python 3, как согласованный тип). Один из возможных способов работы для множества произвольных объектов - сортировка по их repr(). Конечно, это может тратить много лишнего времени и блоков памяти repr() для больших списков и т. Д.

sorted(a, key=repr) == sorted(b, key==repr)

Если объекты все ваши собственные типы, вы можете определить __lt__() на них, чтобы объект знал, как сравнивать себя с другими. Затем вы можете просто отсортировать их и не беспокоиться о параметре key=. Конечно, вы также можете определить __hash__() и использовать Counter, который будет быстрее.

5
ответ дан kindall 25 August 2018 в 06:43
поделиться

Вы можете сортировать оба:

sorted(a) == sorted(b)

Сортировка счетчика также может быть более эффективной (но для этого требуется, чтобы объект был хешируемым).

>>> from collections import Counter
>>> a = [1, 2, 3, 1, 2, 3]
>>> b = [3, 2, 1, 3, 2, 1]
>>> print (Counter(a) == Counter(b))
True
12
ответ дан Mark Byers 25 August 2018 в 06:43
поделиться

Если список содержит элементы, которые не являются хешируемыми (например, список объектов), вы можете использовать Counter Class и функцию id (), такую ​​как:

from collections import Counter
...
if Counter(map(id,a)) == Counter(map(id,b)):
    print("Lists a and b contain the same objects")
3
ответ дан Mars 25 August 2018 в 06:43
поделиться

Пусть a, b перечисляет

def ass_equal(a,b):
try:
    map(lambda x: a.pop(a.index(x)), b) # try to remove all the elements of b from a, on fail, throw exception
    if len(a) == 0: # if a is empty, means that b has removed them all
        return True 
except:
    return False # b failed to remove some items from a

Не нужно делать их хешируемыми или сортировать.

1
ответ дан Umur Kontacı 25 August 2018 в 06:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: