En Python 3.x (y Python 2.7, cuando salga al mercado), se puede utilizar para este collections.Counter:
>>> from collections import Counter
>>> list((Counter([2,2,1,1]) & Counter([1,3,3,1])).elements())
[1, 1]
Aquí es una alternativa usando collections.defaultdict (disponible en Python 2.5 y posteriores). Tiene la buena propiedad de que el orden del resultado es determinista (esencialmente corresponde al orden de la segunda lista).
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
Por estas dos soluciones, el número de ocurrencias de cualquier elemento dado x
en la lista de salida es el mínimo de los números de ocurrencias de x
en las dos listas de entrada. No queda claro a partir de su pregunta si este es el comportamiento que desea.
¿Por qué no desea utilizar conjuntos? –
Tengo elementos duplicados en la lista – Thomas
¿cuáles son los valores de retorno esperados para '[1, 2, 1]' y '[1, 3, 2]'? – SilentGhost