В 3.x Python (и Python 2.7, когда она выйдет), вы можете использовать collections.Counter для этого:
>>> from collections import Counter
>>> list((Counter([2,2,1,1]) & Counter([1,3,3,1])).elements())
[1, 1]
Вот альтернатива, используя collections.defaultdict (доступный в Python 2.5 и выше). Он обладает приятным свойством, что порядок результата детерминирован (он по существу соответствует порядку второго списка).
from collections import defaultdict
def list_intersection(list1, list2):
bag = defaultdict(int)
for elt in list1:
bag[elt] += 1
result = []
for elt in list2:
if elt in bag:
# remove elt from bag, making sure
# that bag counts are kept positive
if bag[elt] == 1:
del bag[elt]
else:
bag[elt] -= 1
result.append(elt)
return result
Для обоих этих решений, число вхождений любого данного элемента x
в списке вывода является минимальным из числа вхождений x
в двух входных списков. Из вашего вопроса неясно, является ли это поведением, которое вы хотите.
Почему вы не хотите использовать наборы? –
У меня есть повторяющиеся элементы в списке – Thomas
Каковы ожидаемые значения возврата для '[1, 2, 1]' и '[1, 3, 2]'? – SilentGhost