12

Получить различия между двумя списками с уникальными элементами

11

У меня есть два списка в Python:

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

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

temp3 = ['Three', 'Four']

Существуют ли быстрые способы сделать это без использования циклов и проверок?

5 ответ(ов)

18

Чтобы получить элементы, которые есть в temp1, но отсутствуют в temp2 (предполагая уникальность элементов в каждом списке), вы можете воспользоваться следующим способом:

list(set(temp1) - set(temp2))

На выходе вы получите:

Out: ['Four', 'Three']

Обратите внимание, что операция асимметрична:

set([1, 2]) - set([2, 3])

Вернет:

Out: set([1])

Это может быть неожиданным, если вы ожидали получить set([1, 3]). Если вам необходимо получить именно set([1, 3]), вы можете воспользоваться методом симметричной разности:

set([1, 2]).symmetric_difference(set([2, 3]))
6

Существующие решения предлагают либо одно, либо другое:

  • Производительность быстрее 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
4.2770634955  # этот ответ
30.7715615392 # ответ matt b

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

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

Результаты:

11.3836875916 # ответ ars
3.63890368748 # этот ответ (в 3 раза быстрее!)
37.7445402279 # ответ matt b
2

Это можно сделать с использованием оператора XOR в Python.

  • Это удалит дубликаты в каждом списке.
  • Это покажет разницу между temp1 и temp2, а также между temp2 и temp1.

set(temp1) ^ set(temp2)
1

Вы можете использовать генерацию списков:

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

Попробуйте сделать так:

temp3 = set(temp1) - set(temp2)

Этот код создаст temp3, содержащий элементы, которые есть в temp1, но отсутствуют в temp2. Использование множеств (set) позволяет эффективно выполнять операции разности между ними.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь