Pythonic способ сравнить два списка и распечатать различия - PullRequest
16 голосов
/ 05 марта 2010

У меня есть два списка, которые гарантированно будут одинаковой длины.Я хочу сравнить соответствующие значения в списке (кроме первого элемента) и распечатать те, которые не совпадают.Вот как я это делаю:

i = len(list1)
if i == 1:
    print 'Nothing to compare'
else:
    for i in range(i):
        if not (i == 0):
            if list1[i] != list2[i]:
                print list1[i]
                print list2[i]

Есть ли лучший способ сделать это?(Python 2.x)

Ответы [ 7 ]

21 голосов
/ 05 марта 2010
list1=[1,2,3,4]
list2=[1,5,3,4]
print [(i,j) for i,j in zip(list1,list2) if i!=j]

Выход:

[(2, 5)]

Редактировать: Легко расширяется, чтобы пропустить n первые элементы (тот же вывод):

list1=[1,2,3,4]
list2=[2,5,3,4]
print [(i,j) for i,j in zip(list1,list2)[1:] if i!=j]
5 голосов
/ 05 марта 2010

Никто не упомянул фильтр:

a = [1, 2, 3]
b = [42, 3, 4]

aToCompare = a[1:]
bToCompare = b[1:]

c = filter( lambda x: (not(x in aToCompare)), bToCompare)
print c
2 голосов
/ 05 марта 2010

Вы можете использовать наборы:

>>> list1=[1,2,3,4]
>>> list2=[1,5,3,4]
>>> set(list1[1:]).symmetric_difference(list2[1:])
set([2, 5])
2 голосов
/ 05 марта 2010

С учетом требования пропустить первую строку:

from itertools import izip
both = izip(list1,list2)
both.next()  #skip the first
for p in (p for p in both if p[0]!=p[1]):
   print pair
  1. Используется izip, версия итератора ( itertools ) zip, для генерации итератора через пары значений. Таким образом, вы не расходуете много памяти, генерируя полный сжатый список.
  2. Он шагает итератор both по одному, чтобы избежать обработки первого элемента и избежать необходимости сравнивать индексы на каждом шаге цикла. Это также делает чтение чище.
  3. Наконец, он проходит через каждый кортеж, возвращаемый генератором, который дает только неравные пары.
2 голосов
/ 05 марта 2010

Для этого в стандартной библиотеке есть класс difflib.SequenceMatcher.

2 голосов
/ 05 марта 2010

edit: упс, не видел часть "игнорировать первый элемент"

from itertools import islice,izip

for a,b in islice(izip(list1,list2),1,None):
    if a != b:
       print a, b
0 голосов
/ 29 января 2019

Вы можете использовать set operation, чтобы найти симметричную разницу (^) между двумя списками. Это один из лучших питоновских способов сделать это.

list1=[1,2,3,4]
list2=[1,5,3,4]

print(set(list1) ^ set(list2))

Так что вывод будет {2, 5}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...