2012-01-05 11 views
10

Eventuali duplicati:
Tuple value by keyOttenere un elemento dalla tupla di tuple in python

come faccio a trovare il nome del paese per avere il suo codice,

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 avere il codice AS, trovare il suo nome senza usare forloop sulla tupla COUNTRIES?

+3

Perché non usi il dizionario? – Sergey

+0

Devo usare le tuple, so che è facile da dettare. – Ahsan

+0

@Sergey: Django utilizza elenchi associati in alcuni punti. –

risposta

19

si può semplicemente fare:

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

Questo crea semplicemente una mappatura tra le sigle e nomi di nazioni. L'accesso alla mappatura è molto veloce: questo è probabilmente il metodo più veloce se si fanno più ricerche, poiché la ricerca del dizionario di Python è molto efficiente.

+0

Sai se la conversione + ricerca è più veloce di un ciclo attraverso le tuple per una partita? – daramarak

+0

@daramarak: per una singola ricerca la creazione di un dizionario dovrebbe essere più lenta. guarda la mia risposta in down ..:/ –

+0

@yi_H: punto interessante sollevato! Ma la complessità temporale per un ** per loop ** è O (n), e l'accesso a una tupla/dizionario è O (1). Stai parlando del tempo impiegato per il casting di tipo? Si prega di specificare la tua logica. –

1

Non è possibile.

In entrambi i

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

o

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

ma questi sono ancora "loop".

+0

Nessun downvote, ma entrambe queste soluzioni sono inefficienti: tutti i Paesi vengono riletti per ogni ricerca, anche se il paese 'AS' viene trovato all'inizio dell'elenco dei Paesi. – EOL

+0

Vuoi dire che è inefficiente * se * ci sono più ricerche. –

+0

Questi metodi sono in realtà * sempre * inefficienti: anche se il paese 'AS' viene trovato proprio all'inizio dell'elenco COUNTRIES, il resto dell'elenco viene comunque letto in modo non necessario. La risposta di Robert King mostra un modo efficace per fare qualcosa di simile. – 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

Questa è una risposta già affermata da molti. Perché ripetersi? –

+1

Non ho visto esempi con il generatore in altri esempi, questo è bello. +1 – Ski

+0

La versione del generatore potrebbe essere resa più breve facendo 'next (paese per codice, nazione in PAESE se codice == 'AD')'. Il builtin 'next (a) -> a.next()'. (Effettivamente, in un micro-benchmark l'incorporato 'next' funzionerà peggio a causa di ciò, ma è comunque un fatto divertente.) C'è in realtà un modo in cui usare l'incorporato' next' è meglio: il suo argomento 'default' . per esempio.'successivo ((Paese per codice, paese in PAESI se codice == 'AD'), Nessuno)' restituirà 'Nessuna' se non c'è corrispondenza di lingua. –

Problemi correlati