Отримайте різницю між двома списками


809

У мене є два списки в Python, такі як:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']

Мені потрібно створити третій список із предметами з першого списку, яких немає у другому. З прикладу я маю отримати:

temp3 = ['Three', 'Four']

Чи існують швидкі способи без циклів і перевірки?


14
Чи гарантовано елементи унікальні? Якщо у вас є , temp1 = ['One', 'One', 'One']і temp2 = ['One'], як ви хочете ['One', 'One']назад, або []?
Майкл Мрозек

@ michael-mrozek вони унікальні.
Макс Фрай

12
Ви хочете зберегти порядок елементів?
Марк Байєрс

Відповіді:


1207
In [5]: list(set(temp1) - set(temp2))
Out[5]: ['Four', 'Three']

Остерігайся цього

In [5]: set([1, 2]) - set([2, 3])
Out[5]: set([1]) 

де ви можете очікувати / хочете, щоб це було рівним set([1, 3]). Якщо ви хочете set([1, 3])як свою відповідь, вам потрібно буде скористатися set([1, 2]).symmetric_difference(set([2, 3])).


27
@Drewdin: Списки не підтримують операнд "-". Однак набори це роблять, і те, що продемонстровано вище, якщо уважно придивитися.
Godsmith

1
дякую, я в кінцевому підсумку використовував set (ListA) .symmetric_difference (ListB)
Дрюдін

43
симетричну різницю можна записати за допомогою: ^ (set1 ^ set2)
Бастіан

10
Будь ласка, ви можете відредагувати свою відповідь і зазначити, що це повертає лише temp1-temp2? .. Як сказано в іншому, щоб повернути всі відмінності, ви повинні використовувати різницю симетричного: list (set (temp1) ^ set (temp2))
rkachach

Чому я отримую, TypeError: 'str' object is not callableколи виконую цю операцію, a = [1,2,2,2,3]іb = [2]
d8aninja

475

Усі існуючі рішення пропонують те чи інше:

  • Швидше виконання O (n * m).
  • Зберегти порядок введення списку.

Але поки що рішення не має обох. Якщо ви хочете обох, спробуйте це:

s = set(temp2)
temp3 = [x for x in temp1 if x not in s]

Тест на продуктивність

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)

Результати:

4.34620224079 # ars' answer
4.2770634955  # This answer
30.7715615392 # matt b's answer

Представлений мною метод, а також збереження порядку також (трохи) швидший, ніж задане віднімання, оскільки він не потребує побудови непотрібного набору. Різниця в продуктивності була б помітнішою, якщо перший список значно довший за другий і якщо хеширование коштує дорого. Ось другий тест, що демонструє це:

init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''

Результати:

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer

2
Додаткова підтримка цієї відповіді: натрапив на випадки використання, коли збереження порядку списку було важливим для виконання. Під час роботи з об'єктами tarinfo або zipinfo я використовував задані віднімання. Щоб виключити вилучення певних об'єктів tarinfo з архіву. Створення нового списку було швидким, але надто повільним під час видобутку. Причина спочатку ухилилася від мене. Виявляється, переупорядкування списку об’єктів tarinfo спричинило величезне покарання за продуктивність. Перехід на метод розуміння списку врятував день.
Рей Томпсон

@MarkByers - можливо, я повинен написати для цього зовсім нове запитання. Але як би це працювало у відриві? Наприклад, якщо мої temp1 та temp2 продовжують змінюватися .. і я хочу додати нову інформацію до temp3?
Ason

@MarkByers - добре звучить. Я трохи про це подумаю. але +1 - чудове рішення.
Ason

Я згоден з @Dejel >>> temp1 = ['Один', 'Два', 'Три', 'Чотири'] >>> temp2 = ['Один', 'Два', 'Шість'] >>> s = set (temp2) >>> temp3 = [x for x in temp1 if x not in s] >>> temp3 ['Three', 'Four']
вушні панелі

3
@haccks Тому що перевірка належності до списку - це операція O (n) (повторення над усім списком), але перевірка належності до набору - O (1).
Марк Байєрс

86
temp3 = [item for item in temp1 if item not in temp2]

15
Якщо temp2перетворити набір раніше, це зробить це трохи ефективнішим.
місячник

3
Правда, залежить, чи дбає про Осконал про дублікати чи ні (оригінальне питання не говорить)
matt

2
Коментар каже, що (списки | кортежі) не мають дублікатів.

1
Я підтримав вашу відповідь, тому що спочатку я вважав, що ви маєте рацію щодо дублікатів. Але item not in temp2і item not in set(temp2)завжди буде повертати ті ж результати, незалежно від того , є дублікати або НЕ temp2.
arekolek

5
Проголосуйте за те, щоб не вимагати змін елементів списку.
Brent

23

Різницю між двома списками (скажімо list1 та list2) можна знайти за допомогою наступної простої функції.

def diff(list1, list2):
    c = set(list1).union(set(list2))  # or c = set(list1) | set(list2)
    d = set(list1).intersection(set(list2))  # or d = set(list1) & set(list2)
    return list(c - d)

або

def diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))  # or return list(set(list1) ^ set(list2))

Використовуючи вищевказану функцію, різницю можна знайти за допомогою diff(temp2, temp1)або diff(temp1, temp2). Обидва дадуть результат ['Four', 'Three']. Вам не потрібно турбуватися про порядок списку або про те, який список потрібно надати першим.

Посилання на документ Python


7
Чому б не встановити (list1) .symmetric_difference (set (list2))?
swietyy

20

Якщо ви хочете, щоб різниця була рекурсивно, я написав пакет для python: https://github.com/seperman/deepdiff

Установка

Встановити з PyPi:

pip install deepdiff

Приклад використання

Імпорт

>>> from deepdiff import DeepDiff
>>> from pprint import pprint
>>> from __future__ import print_function # In case running on Python 2

Цей же об’єкт повертається порожнім

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = t1
>>> print(DeepDiff(t1, t2))
{}

Тип елемента змінився

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:"2", 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{ 'type_changes': { 'root[2]': { 'newtype': <class 'str'>,
                                 'newvalue': '2',
                                 'oldtype': <class 'int'>,
                                 'oldvalue': 2}}}

Значення товару змінилося

>>> t1 = {1:1, 2:2, 3:3}
>>> t2 = {1:1, 2:4, 3:3}
>>> pprint(DeepDiff(t1, t2), indent=2)
{'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Елемент додано та / або вилучено

>>> t1 = {1:1, 2:2, 3:3, 4:4}
>>> t2 = {1:1, 2:4, 3:3, 5:5, 6:6}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff)
{'dic_item_added': ['root[5]', 'root[6]'],
 'dic_item_removed': ['root[4]'],
 'values_changed': {'root[2]': {'newvalue': 4, 'oldvalue': 2}}}

Різна різниця

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world"}}
>>> t2 = {1:1, 2:4, 3:3, 4:{"a":"hello", "b":"world!"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { 'root[2]': {'newvalue': 4, 'oldvalue': 2},
                      "root[4]['b']": { 'newvalue': 'world!',
                                        'oldvalue': 'world'}}}

Різниця рядків 2

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world!\nGoodbye!\n1\n2\nEnd"}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n1\n2\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'values_changed': { "root[4]['b']": { 'diff': '--- \n'
                                                '+++ \n'
                                                '@@ -1,5 +1,4 @@\n'
                                                '-world!\n'
                                                '-Goodbye!\n'
                                                '+world\n'
                                                ' 1\n'
                                                ' 2\n'
                                                ' End',
                                        'newvalue': 'world\n1\n2\nEnd',
                                        'oldvalue': 'world!\n'
                                                    'Goodbye!\n'
                                                    '1\n'
                                                    '2\n'
                                                    'End'}}}

>>> 
>>> print (ddiff['values_changed']["root[4]['b']"]["diff"])
--- 
+++ 
@@ -1,5 +1,4 @@
-world!
-Goodbye!
+world
 1
 2
 End

Зміна типу

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":"world\n\n\nEnd"}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'type_changes': { "root[4]['b']": { 'newtype': <class 'str'>,
                                      'newvalue': 'world\n\n\nEnd',
                                      'oldtype': <class 'list'>,
                                      'oldvalue': [1, 2, 3]}}}

Різниця в списку

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3, 4]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{'iterable_item_removed': {"root[4]['b'][2]": 3, "root[4]['b'][3]": 4}}

Різниця в списку 2:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'iterable_item_added': {"root[4]['b'][3]": 3},
  'values_changed': { "root[4]['b'][1]": {'newvalue': 3, 'oldvalue': 2},
                      "root[4]['b'][2]": {'newvalue': 2, 'oldvalue': 3}}}

Різниця в списку ігнорування порядку чи дублікатів: (з тими ж словниками, що і вище)

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
>>> ddiff = DeepDiff(t1, t2, ignore_order=True)
>>> print (ddiff)
{}

Список, що містить словник:

>>> t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:1, 2:2}]}}
>>> t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, {1:3}]}}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (ddiff, indent = 2)
{ 'dic_item_removed': ["root[4]['b'][2][2]"],
  'values_changed': {"root[4]['b'][2][1]": {'newvalue': 3, 'oldvalue': 1}}}

Набори:

>>> t1 = {1, 2, 8}
>>> t2 = {1, 2, 3, 5}
>>> ddiff = DeepDiff(t1, t2)
>>> pprint (DeepDiff(t1, t2))
{'set_item_added': ['root[3]', 'root[5]'], 'set_item_removed': ['root[8]']}

Названі кортежі:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> t1 = Point(x=11, y=22)
>>> t2 = Point(x=11, y=23)
>>> pprint (DeepDiff(t1, t2))
{'values_changed': {'root.y': {'newvalue': 23, 'oldvalue': 22}}}

Спеціальні об'єкти:

>>> class ClassA(object):
...     a = 1
...     def __init__(self, b):
...         self.b = b
... 
>>> t1 = ClassA(1)
>>> t2 = ClassA(2)
>>> 
>>> pprint(DeepDiff(t1, t2))
{'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

Атрибут об’єкта додано:

>>> t2.c = "new attribute"
>>> pprint(DeepDiff(t1, t2))
{'attribute_added': ['root.c'],
 'values_changed': {'root.b': {'newvalue': 2, 'oldvalue': 1}}}

20

Це можна зробити за допомогою оператора python XOR.

  • Це видалить дублікати у кожному списку
  • Це покаже різницю temp1 від temp2 і temp2 від temp1.

set(temp1) ^ set(temp2)

працює, але чому?
ZakS

найкраща відповідь!
Арцьомій Пранеускі

яка відповідь! так пітонічно !!!! дивовижно
toing_toing

18

найпростіший спосіб,

використовувати set (), різниця (set ())

list_a = [1,2,3]
list_b = [2,3]
print set(list_a).difference(set(list_b))

відповідь є set([1])

може друкувати як список,

print list(set(list_a).difference(set(list_b)))

14

Якщо ви дійсно дивитесь на продуктивність, тоді використовуйте numpy!

Ось повний зошит як суть на Github із порівнянням списку, нумету та панди.

https://gist.github.com/denfromufa/2821ff59b02e9482be15d27f2bbd4451

введіть тут опис зображення


Я оновив ноутбук за посиланням, а також скріншот. Дивно, що панди повільніші, ніж нумізовані навіть при внутрішньому переході на хеш-хет. Частково це може бути пов’язано з оновленням до int64.
denfromufa

13

Я буду кидати, оскільки жодне з теперішніх рішень не дає кортежу:

temp3 = tuple(set(temp1) - set(temp2))

альтернативно:

#edited using @Mark Byers idea. If you accept this one as answer, just accept his instead.
temp3 = tuple(x for x in temp1 if x not in set(temp2))

Як і інші відповіді, які не дають відповіді в цьому напрямку, він зберігає порядок


11

Я хотів чогось, що брало б два списки і могло робити те, що diffвbash робить. Оскільки це запитання з'являється першим під час пошуку "python diff two liste" і не дуже конкретний, я опублікую те, що я придумав.

Використання SequenceMatherз difflibвас може порівняти два списки , як diffробить. Жоден з інших відповідей не скаже вам позицію, де виникає різниця, але ця є. Деякі відповіді дають різницю лише в одному напрямку. Деякі переупорядковують елементи. Деякі не обробляють дублікати. Але це рішення дає вам справжню різницю між двома списками:

a = 'A quick fox jumps the lazy dog'.split()
b = 'A quick brown mouse jumps over the dog'.split()

from difflib import SequenceMatcher

for tag, i, j, k, l in SequenceMatcher(None, a, b).get_opcodes():
  if tag == 'equal': print('both have', a[i:j])
  if tag in ('delete', 'replace'): print('  1st has', a[i:j])
  if tag in ('insert', 'replace'): print('  2nd has', b[k:l])

Цей результат:

both have ['A', 'quick']
  1st has ['fox']
  2nd has ['brown', 'mouse']
both have ['jumps']
  2nd has ['over']
both have ['the']
  1st has ['lazy']
both have ['dog']

Звичайно, якщо ваша заява робить ті самі припущення, що й інші відповіді, ви отримаєте найбільше користь від них. Але якщо ви шукаєте справжнєdiff функціональність, то це єдиний шлях.

Наприклад, жоден з інших відповідей не міг впоратися:

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

Але це робить:

  2nd has [5, 4, 3, 2]
both have [1]
  1st has [2, 3, 4, 5]


10

це може бути навіть швидше, ніж розуміння списку Марка:

list(itertools.filterfalse(set(temp2).__contains__, temp1))

7
Можливо, хочете включити from itertools import filterfalseсюди шматочок. Також зауважте, що це не повертає послідовність, як інші, вона повертає ітератор.
Метт Луонго

7

Ось Counterвідповідь на найпростіший випадок.

Це коротше, ніж вище, ніж двостороння, оскільки воно робить саме те, що задається питанням: створити список того, що є в першому списку, а не у другому.

from collections import Counter

lst1 = ['One', 'Two', 'Three', 'Four']
lst2 = ['One', 'Two']

c1 = Counter(lst1)
c2 = Counter(lst2)
diff = list((c1 - c2).elements())

Крім того, залежно від ваших уподобань для читабельності, це дозволяє зробити гідний однорівень:

diff = list((Counter(lst1) - Counter(lst2)).elements())

Вихід:

['Three', 'Four']

Зауважте, що ви можете видалити list(...)виклик, якщо ви просто перебираєте його.

Оскільки це рішення використовує лічильники, воно обробляє величини належним чином у порівнянні з багатьма наборами відповідей. Наприклад, на цьому вході:

lst1 = ['One', 'Two', 'Two', 'Two', 'Three', 'Three', 'Four']
lst2 = ['One', 'Two']

Вихід:

['Two', 'Two', 'Three', 'Three', 'Four']

5

Ви можете використовувати наївний метод, якщо елементи дистрибутиву будуть відсортовані та встановлені.

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

print list1[len(list2):]

або з нативними методами набору:

subset=set(list1).difference(list2)

print subset

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print "Naive solution: ", timeit.timeit('temp1[len(temp2):]', init, number = 100000)
print "Native set solution: ", timeit.timeit('set(temp1).difference(temp2)', init, number = 100000)

Наївне рішення: 0,0787101593292

Рішення для рідного набору: 0,998837615564


5

Я занадто пізно в грі для цього, але ви можете порівняти продуктивність деяких з вищезгаданих кодів з цим, два найшвидших суперника,

list(set(x).symmetric_difference(set(y)))
list(set(x) ^ set(y))

Прошу вибачення за елементарний рівень кодування.

import time
import random
from itertools import filterfalse

# 1 - performance (time taken)
# 2 - correctness (answer - 1,4,5,6)
# set performance
performance = 1
numberoftests = 7

def answer(x,y,z):
    if z == 0:
        start = time.clock()
        lists = (str(list(set(x)-set(y))+list(set(y)-set(y))))
        times = ("1 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 1:
        start = time.clock()
        lists = (str(list(set(x).symmetric_difference(set(y)))))
        times = ("2 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 2:
        start = time.clock()
        lists = (str(list(set(x) ^ set(y))))
        times = ("3 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 3:
        start = time.clock()
        lists = (filterfalse(set(y).__contains__, x))
        times = ("4 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 4:
        start = time.clock()
        lists = (tuple(set(x) - set(y)))
        times = ("5 = " + str(time.clock() - start))
        return (lists,times)

    elif z == 5:
        start = time.clock()
        lists = ([tt for tt in x if tt not in y])
        times = ("6 = " + str(time.clock() - start))
        return (lists,times)

    else:    
        start = time.clock()
        Xarray = [iDa for iDa in x if iDa not in y]
        Yarray = [iDb for iDb in y if iDb not in x]
        lists = (str(Xarray + Yarray))
        times = ("7 = " + str(time.clock() - start))
        return (lists,times)

n = numberoftests

if performance == 2:
    a = [1,2,3,4,5]
    b = [3,2,6]
    for c in range(0,n):
        d = answer(a,b,c)
        print(d[0])

elif performance == 1:
    for tests in range(0,10):
        print("Test Number" + str(tests + 1))
        a = random.sample(range(1, 900000), 9999)
        b = random.sample(range(1, 900000), 9999)
        for c in range(0,n):
            #if c not in (1,4,5,6):
            d = answer(a,b,c)
            print(d[1])

5

Ось кілька простих способів збереження порядку для розмежування двох списків рядків.

Код

Незвичний підхід із використанням pathlib:

import pathlib


temp1 = ["One", "Two", "Three", "Four"]
temp2 = ["One", "Two"]

p = pathlib.Path(*temp1)
r = p.relative_to(*temp2)
list(r.parts)
# ['Three', 'Four']

Це передбачає, що обидва списки містять рядки з еквівалентними початками. Докладніше див. У документах . Зауважте, він не особливо швидкий порівняно із встановленими операціями.


Проста реалізація з використанням itertools.zip_longest:

import itertools as it


[x for x, y in it.zip_longest(temp1, temp2) if x != y]
# ['Three', 'Four']

1
Рішення itertools працює тільки тоді , коли елементи temp1і temp2лінії добре. Якщо ви, наприклад, перевернете елементи на початку temp2або вставите якесь інше значення на початку temp2, listcomp просто поверне ті самі елементи, що і вtemp1
KenHBS

Так, це особливість цих підходів. Як вже було сказано, ці рішення зберігають порядок - вони припускають певний відносний порядок між списками. Неупорядкованим рішенням було б відрізняти два набори.
піланг

4

Це ще одне рішення:

def diff(a, b):
    xa = [i for i in set(a) if i not in b]
    xb = [i for i in set(b) if i not in a]
    return xa + xb


4

Скажімо, у нас є два списки

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

з двох вищеперелічених списків ми бачимо, що пункти 1, 3, 5 існують у списку2, а пункти 7, 9 - ні. З іншого боку, пункти 1, 3, 5 існують у списку1, а пункти 2, 4 - ні.

Яке найкраще рішення повернути новий список, що містить пункти 7, 9 та 2, 4?

Усі відповіді вище знаходимо рішення, а що найоптимальніше?

def difference(list1, list2):
    new_list = []
    for i in list1:
        if i not in list2:
            new_list.append(i)

    for j in list2:
        if j not in list1:
            new_list.append(j)
    return new_list

проти

def sym_diff(list1, list2):
    return list(set(list1).symmetric_difference(set(list2)))

Використовуючи timeit, ми можемо побачити результати

t1 = timeit.Timer("difference(list1, list2)", "from __main__ import difference, 
list1, list2")
t2 = timeit.Timer("sym_diff(list1, list2)", "from __main__ import sym_diff, 
list1, list2")

print('Using two for loops', t1.timeit(number=100000), 'Milliseconds')
print('Using two for loops', t2.timeit(number=100000), 'Milliseconds')

повертає

[7, 9, 2, 4]
Using two for loops 0.11572412995155901 Milliseconds
Using symmetric_difference 0.11285737506113946 Milliseconds

Process finished with exit code 0

3

однолінійна версія рішення arulmr

def diff(listA, listB):
    return set(listA) - set(listB) | set(listA) -set(listB)

3

якщо ви хочете щось більше, як набір змін ... можна скористатися Counter

from collections import Counter

def diff(a, b):
  """ more verbose than needs to be, for clarity """
  ca, cb = Counter(a), Counter(b)
  to_add = cb - ca
  to_remove = ca - cb
  changes = Counter(to_add)
  changes.subtract(to_remove)
  return changes

lista = ['one', 'three', 'four', 'four', 'one']
listb = ['one', 'two', 'three']

In [127]: diff(lista, listb)
Out[127]: Counter({'two': 1, 'one': -1, 'four': -2})
# in order to go from lista to list b, you need to add a "two", remove a "one", and remove two "four"s

In [128]: diff(listb, lista)
Out[128]: Counter({'four': 2, 'one': 1, 'two': -1})
# in order to go from listb to lista, you must add two "four"s, add a "one", and remove a "two"

2

Ми можемо обчислити перетин мінус об'єднання списків:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two', 'Five']

set(temp1+temp2)-(set(temp1)&set(temp2))

Out: set(['Four', 'Five', 'Three']) 

2

Це можна вирішити одним рядком. Питання задається двома списками (temp1 і temp2), що повертають їх різницю в третьому списку (temp3).

temp3 = list(set(temp1).difference(set(temp2)))

1

Ось простий спосіб розрізнити два списки (незалежно від вмісту), ви можете отримати результат, як показано нижче:

>>> from sets import Set
>>>
>>> l1 = ['xvda', False, 'xvdbb', 12, 'xvdbc']
>>> l2 = ['xvda', 'xvdbb', 'xvdbc', 'xvdbd', None]
>>>
>>> Set(l1).symmetric_difference(Set(l2))
Set([False, 'xvdbd', None, 12])

Сподіваюсь, це допоможе.


0

Я вважаю за краще використовувати перетворення в набори, а потім використовуючи функцію "різниця ()". Повний код:

temp1 = ['One', 'Two', 'Three', 'Four'  ]                   
temp2 = ['One', 'Two']
set1 = set(temp1)
set2 = set(temp2)
set3 = set1.difference(set2)
temp3 = list(set3)
print(temp3)

Вихід:

>>>print(temp3)
['Three', 'Four']

Це найпростіше підкреслити та перенести в майбутньому, якщо ви працюєте з великими даними, перетворення їх у набори видалить дублікати, якщо дублікати не потрібно. Сподіваюся, що це допомагає ;-)


-1
(list(set(a)-set(b))+list(set(b)-set(a)))

3
Окрім надання відповіді, чи можете ви дати пояснення, як це працює / стосується цього конкретного питання? Відповіді та рішення чудові, але детальні вказівки та пояснення нескінченно кращі.
Busse

-1
def diffList(list1, list2):     # returns the difference between two lists.
    if len(list1) > len(list2):
        return (list(set(list1) - set(list2)))
    else:
        return (list(set(list2) - set(list1)))

наприклад, якщо list1 = [10, 15, 20, 25, 30, 35, 40]і list2 = [25, 40, 35]тоді буде повернутий списокoutput = [10, 20, 30, 15]


Ви не можете зробити це так для різницької роботи. Навіть у випадку цілих чисел, якщо ви скажете функції виконувати "a - b", передбачається відняти "b" лише від "a", незалежно від того, "b" більше "a" чи іншим чином. Аналогічний випадок зі списком та наборами. A - B і B - А обидва можуть бути дійсними операціями незалежно від довжин A і B, вам потрібно виключити вміст B з A для виконання A - B.
Abu Talha Датська
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.