2010-01-22 14 views

Respuesta

13

La misma forma que lo haría con la mano:

seen = set() 
repeated = set() 
for l in list_of_lists: 
    for i in set(l): 
    if i in seen: 
     repeated.add(i) 
    else: 
     seen.add(i) 

Por cierto, aquí está el forro (sin contar la importación) que algunas personas estaban buscando (debe ser menos eficiente que el otro enfoque)

from itertools import * 
reduce(set.union, (starmap(set.intersection, combinations(map(set, ll), 2)))) 
+0

¡Gran uso del conjunto! – Khelben

+7

Solo tenga cuidado, ya que 'l' también necesita 'establecerse', o obtendrá falsos positivos en [[1,1], [2,2]] – Khelben

+0

+1 para la legibilidad – tback

-2

aplanar, clasificar, 1 para el bucle comparar números antes y después de

+0

Esto sería un error si un número aparece dos veces en el misma lista. –

+0

Si se aplana primero, obtendría un "falso positivo" en la entrada, como: [[1, 1], [2, 2]] – truppo

1

Puede usar un diccionario para obtener el recuento de cada referencia

from collections import defaultdict 

init_list = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
#defaultdict, every new key will have a int(0) as default value 
d = defaultdict(int) 
for values in init_list: 
    #Transform each list in a set to avoid false positives like [[1,1],[2,2]] 
    for v in set(values): 
    d[v] += 1 

#Get only the ones that are more than once 
final_list = [ value for value,number in d.items() if number > 1 ] 
+0

Parece un buen trabajo para 'collections.defaultdict'. – muhuk

+0

@muhuk. ¡Sí! ¡Estás absolutamente en lo correcto! Cambié el código. La biblioteca estándar de Python es realmente grande y está llena de cosas útiles ... – Khelben

0
l=[[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
d={} 
for x in l: 
    for y in x: 
     if not d.has_key(y): 
      d[y]=0 
     d[y]+=1 
[x for x,y in d.iteritems() if y>1] 
3

: http://docs.python.org/library/stdtypes.html#set

#!/usr/bin/python 

ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
ls = [set(l) for l in ll] 

su = ls[0] #union 
ssd = ls[0] #symmetric_difference 
for s in ls[1:]: 
    su = su.union(s) 
    ssd = ssd.symmetric_difference(s) 

result = su.difference(ssd) 
print list(result) 

=>

[3, 5, 7] 

revisar y adoptar FP,

ll = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 

u = reduce(set.union, map(set, ll)) 
sd = reduce(set.symmetric_difference, map(set, ll)) 
print u - sd 

=>

[3, 5, 7] 
+0

Actualmente su solución no es correcta con mi caso de prueba como 'lst_of_lst = [[65L, 66L, 81L, 95L, 96L, 128L, 171L, 193L, 218L , 304L, 305L, 338L, 353L, 355L, 357L, 412L], [86L, 98L, 154L, 356L], [75L, 154L], [38L, 57L, 65L, 145L, 175L, 264L, 325L, 420L, 429L, 439L], [75L, 161L], [66L, 109L, 128L, 137L, 142L, 154L, 183L, 184L, 187L, 203L, 233L, 285L, 289L, 343L]] 'el resultado debe ser '[128L, 65L, 66L, 154L, 75L]', pero su solución falla '154L' – LancelotHolmes

1

Prueba esto:

data = [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [1,2,3]] 

res = set() 

for i in data: 
    for j in data: 
     if i is not j: 
      res |= set(i) & set(j) 

print res 
5

manera más limpia, probablemente sería utilizar a reducir:

def findCommon(L): 
    def R(a, b, seen=set()): 
     a.update(b & seen) 
     seen.update(b) 
     return a 
    return reduce(R, map(set, L), set()) 

result = findCommon([[1,2,3], [3,4,5], [5,6,7], [7,8,9]]) 

El resultado es un conjunto, pero sólo lo hacen list(result) si realmente necesitas una lista

+0

+1 para programación funcional. –

+0

@Dyno la variable 'seen' contiene un estado mutable" oculto "entre llamadas ... la programación funcional no debe basarse en los efectos secundarios (y es un peligro si no son explícitos, apuesto a que la mayoría de la gente no se daría cuenta) lo visto es jugar el rol de una variable "estática" en lugar de un argumento normal) – fortran

+0

@fortran: El uso típico de funciones como R es una vez, ya que se ubican dentro de otra función y no a nivel de módulo. Actualizaré la respuesta para que quede más claro. – truppo

1
>>> sets = [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] 
>>> seen = set() 
>>> duplicates = set() 
>>> 
>>> for subset in map(set, sets) : 
...  duplicates |= (subset & seen) 
...  seen |= subset 
... 
>>> print(duplicates) 
set([3, 5, 7]) 
>>> 

He intentado obtener una respuesta de una línea con mapa/reducir, pero todavía no puedo conseguirlo.

0

Aquí es mi go:

seen = set() 
result = set() 
for s in map(set, [[1,2,3], [3,4,5], [5,6,7], [7,8,9]]): 
    result.update(s & seen) 
    seen.update(s) 
print result 

Esta impresora:

set([3, 5, 7]) 
2

Otra solución simple (una línea):

set.intersection(*[set(list) for list in list_of_lists]) 
+0

Claramente la mejor respuesta, ¡gracias! –

Cuestiones relacionadas