Intersección de la lista de Python con elementos no únicos

Tengo dos cadenas y me gustaría tener la intersección en ellas, incluidos los elementos duplicados:

str_a = "aabbcc" str_b = "aabd" list(set(str_a) & set(str_b)) >> "ab" 

Me gustaría tenerlo de vuelta:

 >> "aab" 

¿Algunas ideas?

Los conjuntos múltiples se implementan en Python 2.7 o posterior como objetos de Counter (mutables). Puede realizar muchas de las mismas operaciones que puede realizar para conjuntos, como unión, intersección, diferencia (aunque los conteos pueden ser negativos), etc .:

 from collections import Counter as mset 

Solución:

 (mset("aabbcc") & mset("aabd")).elements() 

Más detalles:

 >>> intersection = mset("aabbcc") & mset("aabd") Counter({'a': 2, 'b': 1}) >>> list(intersection.elements()) ['a', 'a', 'b'] >>> ''.join(intersection.elements()) 'aab' 

Puede usar ''.join si desea una cadena, o list() si desea una lista, aunque lo mantendría en un formato iterable como intersection.elements() .

Usa collections.Counter Encuentra cada palabra y usa estos como conjuntos:

 >>> from collections import Counter >>> str_a, str_b = 'aabbcc', 'aabd' >>> Counter(str_a) & Counter(str_b) Counter({'a': 2, 'b': 1}) >>> ''.join((Counter(str_a) & Counter(str_b)).elements()) 'aab' 

El Counter es una subclase de dict , pero una que cuenta todos los elementos de una secuencia con la que se inicializa. Por lo tanto, "aabbcc" convierte en Counter({'a': 2, 'b': 2, 'c': 2}) .

Los contadores actúan como conjuntos múltiples, ya que cuando usa 2 en una intersección como la anterior, sus conteos se configuran a los valores mínimos encontrados en cada contador, ignorando cualquier cosa cuyo conteo caiga a 0. Si tuviera que calcular su unión, los conteos máximos serían ser utilizado en su lugar.