2013-02-24 2 views
5

Если я хочу, чтобы найти что-то в списке в питоне я могу использовать «в» оператора:Альтернатива для «в» оператора для вложенных списков

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

Но что я должен делать, если я хочу, чтобы найти что-то во вложенном списке?

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

Возможно ли это сделать в одной строке без петли, например?

Спасибо!

+1

На самом деле это вложенный кортеж, но это не имеет значения. –

ответ

8

Вы, вероятно, хотите any:

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

Какая-то петля неизбежна, хотя.

+0

Ах, отлично, спасибо :) Я не знал, что могу подключить этих операторов statemens + в одну строку. Благодаря! – Eknoes

1

Вы также могли бы сделать это с in

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

EDIT: этот метод проверки только если foo является, как кулак элемент.

Для поиска в 'Foo' элемента (любой):

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

Некоторых более попробовать:

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

Это не делает то, что вы думаете. '[x [1] для x в списке]' просто ищет второй элемент каждого внутреннего кортежа, то есть '['bar', 'foo']'. – chmullig

+0

@chmullig Да, вы правы. Теперь обновил мой ответ Спасибо! –

1

Если у вас есть список итерируемых с произвольной глубиной, распрямите ее первым:

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) 

Печать:

True 
True 
False 
1

Вы можете использовать itertools.chain так:

from itertools import chain 

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

print 4 in chain(*nested__seq) 

PS: вы не должны переопределять bultins как «список»

2

Это оскорбительно, но вы можете сделать это в одной строке довольно легко.

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

И это ваш метод Хорошо! –