2013-02-27 25 views
26

istnieje Mam listę krotek, które wyglądają jak:Sprawdź, czy element krotki krotek

CODES = (
    ('apple', 'reddelicious'), 
    ('caramel', 'sweetsticky'), 
    ('banana', 'yellowfruit'), 
) 

Jaki jest najlepszy sposób, aby sprawdzić, czy wartość istnieje w tej krotki? Na przykład chcę, aby móc powiedzieć:

'apple' in CODES 

i dostać prawda

Odpowiedz

40

Szukasz any():

if any('apple' in code for code in CODES): 
    ... 

połączeniu z prostym generator expression, to robi to zadanie. Wyrażenie generatora przyjmuje każdą krotkę i daje True, jeśli zawiera ona 'apple'. any() następnie zwraca True, gdy pierwszy żądany element zwraca True (w przeciwnym razie, False). Dlatego robi to, czego chcesz. Dobrze się też czyta - , jeśli którakolwiek z krotek zawiera 'apple'.

Jeśli robisz to ogromną ilość czasu i potrzebują wydajności, to może być warte co zbiór wszystkich wartości, które pozwalają to zrobić bardzo szybko:

cache = set(itertools.chain.from_iterable(CODES))) 

Naturalnie konstruowania będzie to powolne i korzystaj z pamięci, więc nie byłoby to dobrym pomysłem, chyba że będziesz potrzebował dużej wydajności i wykonasz wiele testów członkostwa.

+0

co, jeśli zamiast sprawdzać istnienie - chciałem uzyskać drugą wartość? W tym przypadku "reddelicious"? –

+4

W tym przypadku używasz niewłaściwej struktury danych, użyj 'dict', a następnie po prostu wykonaj' CODES ["apple"] '(i złap" KeyError ", jeśli go tam nie ma). –

+1

@ 9-bitów użyj po prostu 'dic = dict (CODES)', to zwróci słownik. A następnie 'dic ['apple']' spowoduje '' reddelicious''. –

7

Można użyć itertools.chain():

Używanie go in spowoduje zwarcia, podobny do any().

In [30]: CODES = (
    ....:  ('apple', 'reddelicious'), 
    ....:  ('caramel', 'sweetsticky'), 
    ....:  ('banana', 'yellowfruit'), 
    ....:) 


In [31]: from itertools import chain 

In [32]: 'apple' in chain(*CODES) 
Out[32]: True 

In [33]: 'foo' in chain(*CODES) 
Out[33]: False 

Dla wydajności porównań można sprawdzić mój other answer.

+2

+1, Jest to rozsądny sposób, aby to zrobić - nie jestem pewien, w jaki sposób porównuje wydajność. Chociaż powinieneś użyć 'chain.from_iterable()' over 'chain (*)'. –

+0

@Lattyware Myślę, że zarówno jak "any()" i moja metoda robią zwarcia, więc różnica wydajności powinna być znikoma dla dużych danych. –

Powiązane problemy