2013-02-24 21 views
5

Jeśli chcę coś znaleźć na liście w python mogę korzystać z „w” Operator:Alternatywa dla „w” operatora dla zagnieżdżonych list

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

Ale co zrobić, jeśli chcę znaleźć coś w zagnieżdżonej liście?

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

Czy można to zrobić w jednym rzędzie bez pętli for?

Dzięki!

+1

Właściwie to zagnieżdżona krotka, ale to nie ma znaczenia. –

Odpowiedz

8

Prawdopodobnie chcesz any:

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

Jakiś pętli jest nieuniknione mimo.

+0

Ah perfect, dziękuję :) Nie wiedziałem, że mogę połączyć te statemens + operatorów w jednej linii. Dzięki! – Eknoes

1

Można również zrobić to z in

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

EDIT: ten test metody tylko wtedy foo jest jak pięść elementem.

Aby wyszukać jako 'foo' elementu (dowolna):

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

Niektóre bardziej try:

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

To nie robi tego, co myślisz. '[x [1] dla x na liście]' po prostu przeszukuje drugi element każdej wewnętrznej krotki, tj. '['bar', 'foo']'. – chmullig

+0

@chmullig Tak, masz rację. Teraz zaktualizowałem moją odpowiedź Dzięki! –

1

Jeśli masz listę iterables z dowolną głębokość, spłaszczyć je najpierw:

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) 

Wydruki:

True 
True 
False 
1

Można użyć itertools.chain tak:

from itertools import chain 

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

print 4 in chain(*nested__seq) 

PS: nie powinno przesłonić bultins jak „liście”

2

To obraża, ale można to zrobić w jednej linii dość łatwo.

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

I to jest twoja metoda Dobra! –