2012-01-05 12 views
10

Duplicar posibles:
Tuple value by keyConseguir un elemento de la tupla de tuplas en python

¿Cómo encuentro el nombre del país por tener su código,

COUNTRIES = (
    ('AF', _(u'Afghanistan')), 
    ('AX', _(u'\xc5land Islands')), 
    ('AL', _(u'Albania')), 
    ('DZ', _(u'Algeria')), 
    ('AS', _(u'American Samoa')), 
    ('AD', _(u'Andorra')), 
    ('AO', _(u'Angola')), 
    ('AI', _(u'Anguilla')) 
) 

I tener código AS, encontrar su nombre sin usar forloop en COUNTRIES tupla?

+3

¿Por qué no usas el diccionario? – Sergey

+0

tengo que usar tuplas, sé que es fácil en dict. – Ahsan

+0

@Sergey: Django usa listas de asociaciones en algunos lugares. –

Respuesta

19

simple que puede hacer:

countries_dict = dict(COUNTRIES) # Conversion to a dictionary mapping 
print countries_dict['AS'] 

Esto simplemente crea una asignación entre las abreviaturas de países y nombres de países. El acceso a la asignación es muy rápido: este es probablemente el método más rápido si haces múltiples búsquedas, ya que la búsqueda del diccionario de Python es muy eficiente.

+0

¿Sabes si la conversión + búsqueda es más rápida que recorrer las tuplas para encontrar una coincidencia? – daramarak

+0

@daramarak: para una búsqueda única, la creación de un diccionario debe ser más lenta. ver mi respuesta downvoted ..:/ –

+0

@yi_H: punto interesante planteado! Pero la complejidad de tiempo para un ** for loop ** es O (n), y el acceso a una tupla/diccionario es O (1). ¿Estás hablando del tiempo que se consume para el lanzamiento de tipos? Por favor, especifique su lógica. –

1

No puede.

De cualquier

[x[1] for x in COUNTRIES if x[0] == 'AS'][0] 

o

filter(lambda x: x[0] == 'AS', COUNTRIES)[0][1] 

pero éstos siguen siendo "loops".

+0

No hay votación negativa, pero ambas soluciones son ineficientes: todos los países se vuelven a leer para cada búsqueda, incluso si el país 'AS' se encuentra al principio de la lista de países. – EOL

+0

Quiere decir que es ineficiente * si * hay varias búsquedas. –

+0

Estos métodos son en realidad * siempre * ineficaces: incluso si el país 'AS' se encuentra al principio de la lista COUNTRIES, el resto de la lista se leerá de todos modos innecesariamente. La respuesta de Robert King muestra una forma eficiente de hacer algo similar. – EOL

3
COUNTRIES = (
    ('AF', (u'Afghanistan')), 
    ('AX', (u'\xc5land Islands')), 
    ('AL', (u'Albania')), 
    ('DZ', (u'Algeria')), 
    ('AS', (u'American Samoa')), 
    ('AD', (u'Andorra')), 
    ('AO', (u'Angola')), 
    ('AI', (u'Anguilla')) 
) 

print (country for (code, country) in COUNTRIES if code=='AD').next() 
#>>> Andorra 

print next((country for (code, country) in COUNTRIES if code=='AD'), None) 
#Andorra 
print next((country for (code, country) in COUNTRIES if code=='Blah'), None) 
#None 

# If you want to do multiple lookups, the best is to make a dict: 
d = dict(COUNTRIES) 
print d['AD'] 
#>>> Andorra 
+2

Esta es una respuesta ya establecida por muchos. ¿Por qué te repites? –

+1

No he visto ejemplos con el generador en otros ejemplos, esto es bueno. +1 – Ski

+0

La versión del generador podría acortarse haciendo 'next (país por código, país en COUNTRIES si código == 'AD')'. El siguiente 'siguiente (a) -> a.next()'. (Es cierto que en un micro-benchmark, el siguiente 'siguiente' funcionará peor debido a esto, pero es un hecho divertido, de todos modos.) En realidad, hay una manera de usar el siguiente' build' integrado: su argumento 'default' . p.ej.'next ((país por código, país en COUNTRIES si código == 'AD'), None)' devolverá 'None' si no hay coincidencia de idioma. –

Cuestiones relacionadas