2015-04-19 20 views
9

ho due liste:Come scoprire se gli elementi di una lista si trovano in un'altra?

A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]] 
B = [12, 5] 

Sto cercando di scoprire quale elenca in A contenere gli elementi in B (ordine non importa) e di sbarazzarsi di tutto il resto delle liste.

In questo caso le risposte sono:

[[4, 5, 10, 12], [2, 5, 12, 13], [4, 5, 6, 12]] 

Se cambiamo B e facciamo B = [13], la risposta sarebbe:

[[2, 5, 13, 14], [2, 5, 12, 13]] 

risposta

6

È possibile utilizzare set.issubset con una lista di comprensione, utilizzando A[:] cambierà l'oggetto originale/elenco A:

A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]] 
B = [12, 5] 
st = set(B) 

A [:] = [sub for sub in A if st.issubset(sub)] 

print(A) 
[[4, 5, 10, 12], [2, 5, 12, 13], [4, 5, 6, 12]] 

Lo stesso vale per B = [13]

A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]] 
B = [13] 
st = set(B) 

A [:] = [sub for sub in A if st.issubset(sub)] 

print(A) 
[[2, 5, 13, 14], [2, 5, 12, 13]] 

set objects

s.issubset (t) s prova < = t se ogni elemento in s è in t

Per molto grande A o se si dispone di restrizioni di memoria è possibile utilizzare un'espressione generatore:

A [:] = (sub for sub in A if st.issubset(sub)) 

Se l'ordine non conta mai ed è possibile impostare, suggerirei di utilizzarli sin dall'inizio. Fare ricerche sugli insiemi sarà molto più efficiente.

Alcune timing su un un po 'più grande:

In [23]: A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12],[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12],[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]] 

In [24]: B = [12, 5]         
In [25]: timeit filter(lambda x: all(y in x for y in B), A) 
100000 loops, best of 3: 9.45 µs per loop 

In [26]: %%timeit          
st = set(B) 
[sub for sub in A if st.issubset(sub)] 
    ....: 
100000 loops, best of 3: 3.88 µs per loop 
map(lambda x: not B_set-set(x), A) 
In [27]: %%timeit 
....: B_set = set(B) 
....: map(lambda x: not B_set-set(x), A) 
....: 
100000 loops, best of 3: 6.95 µs per loop 

Se hai già avuto gli elementi memorizzati come set in A:

In [33]: %%timeit        
st = set(B) 
[sub for sub in A if sub >= st] 
....: 
1000000 loops, best of 3: 1.12 µs per loop 
+0

Stiamo eliminando le risposte degli altri utenti? (non mio) –

+0

@PedroLobito. Non so cosa intendi? –

+0

un sacco di risposte dove cancellato su questa risposta. –

1

È possibile utilizzare filter in combinazione con all qui:

print filter(lambda x: all(y in x for y in B), A) 

Risposta un po 'più efficiente:

B_set = set(B) 
print map(lambda x: not B_set-set(x), A)