2013-02-24 12 views
5

Se voglio trovare qualcosa in un elenco in python posso usare il 'in' operatore:alternativo per 'in' operatore per le liste nidificate

list = ['foo', 'bar'] 
'foo' in list #returns True 

Ma che cosa devo fare se voglio trovare qualcosa in una lista annidata?

list = [('foo', 'bar'), ('bar', 'foo')] 
'foo' in list #returns False 

È possibile farlo in una riga senza un ciclo for, ad esempio?

Grazie!

+1

In realtà si tratta di una tupla nidificata, ma non importa. –

risposta

8

probabilmente avrete bisogno any:

>>> list = [('foo', 'bar'), ('bar', 'foo')] 
>>> any('foo' in e for e in list) 
True 

Una sorta di ciclo è inevitabile però.

+0

Ah perfetto, grazie :) Non sapevo di poter collegare questi statemi + operatori in una riga. Grazie! – Eknoes

1

Si potrebbe anche fare questo con in

>>> list = [('foo', 'bar'), ('bar', 'foo')] 
>>> 'foo' in (x[1] for x in list) 
True 

EDIT: questo metodo di controllo solo se foo è elemento di pugno.

Per cercare come 'foo' un elemento (qualsiasi):

>>>'foo' in reduce(lambda x,y: x+y, list) 
True 

Qualche altro tentativo:

In [7]: list 
Out[7]: [('foo', 'me', 'bar'), ('bar', 'foo', 'you')] 
In [8]: 'me' in reduce(lambda x,y: x+y, list) 
Out[8]: True 

In [9]: 'you' in reduce(lambda x,y: x+y, list) 
Out[9]: True 
+0

Questo non fa quello che pensi che faccia. '[x [1] per x nella lista]' cerca solo il secondo elemento di ogni tupla interna, ovvero '['bar', 'foo']'. – chmullig

+0

@chmullig Sì, sei corretto. Ora aggiornato la mia risposta Grazie! –

1

Se si dispone di un elenco di iterables con profondità arbitraria, appiattirla prima:

import collections 

li= [('foo', 'bar'), ('bar', 'foo'),[[('deeper',('foobar'))]]] 

def flatten(l): 
    for el in l: 
     if isinstance(el, collections.Iterable) and not isinstance(el, basestring): 
      for sub in flatten(el): 
       yield sub 
     else: 
      yield el 

print 'deeper' in flatten(li) 
print 'foo' in flatten(li) 
print 'nope' in flatten(li) 

Stampe:

True 
True 
False 
1

Si potrebbe usare itertools.chain così:

from itertools import chain 

nested__seq = [(1,2,3), (4,5,6)] 

print 4 in chain(*nested__seq) 

PS: Non si dovrebbe ignorare bultins come "lista"

2

E 'abusivo, ma è possibile farlo in una linea abbastanza facilmente.

mainlist = [('foo', 'bar'), ('bar', 'foo')] 
[elem for elem in sublist for sublist in mainlist] #['bar', 'bar', 'foo', 'foo'] 

'foo' in [elem for elem in sublist for sublist in mainlist] # True 
+0

E questo è il tuo metodo Bene! –

Problemi correlati