Accedi a un elemento arbitrario in un dizionario in Python


507

Se a mydictnon è vuoto, accedo a un elemento arbitrario come:

mydict[mydict.keys()[0]]

C'è un modo migliore per farlo?


3
Quello che ha detto ... questa è davvero una domanda valida solo se c'è un solo elemento nel dict, o se non ti interessa quale ritorno.
royal

5
Sì, ho solo bisogno di accedere a qualunque elemento del dict, quindi è per questo che voglio accedere al primo elemento.
Stan,

2
@Stan: ma come ha detto Greg, non esiste un "primo" elemento definito in dict. quindi forse dovresti cambiare la tua domanda, solo per essere chiari
tdihp

10
Penso che sia una domanda valida. Se devi accedere a un elemento arbitrario e sei sicuro che il dict non sia vuoto, potrebbe essere una buona idea chiedere il "primo", perché il numero di elementi potrebbe non essere noto.
Kap

7
@MichaelScheper Bisogna cast lista: list(mydict.keys())[0].
Daniel Moskovich,

Risposte:


600

Su Python 3, in modo non distruttivo e iterativo:

next(iter(mydict.values()))

Su Python 2, in modo non distruttivo e iterativo:

mydict.itervalues().next()

Se vuoi che funzioni sia in Python 2 che in 3, puoi usare il sixpacchetto:

six.next(six.itervalues(mydict))

anche se a questo punto è abbastanza criptico e preferirei preferire il tuo codice.

Se si desidera rimuovere qualsiasi elemento, fare:

key, value = mydict.popitem()

Nota che "primo" potrebbe non essere un termine appropriato qui perché dictnon è un tipo ordinato in Python <3.6. Python 3.6+ dictssono ordinati.


35
Non intendi dict.iterkeys().next()?
John Machin,

12
@ John Machin: Beh, sembra che la domanda abbia accesso al valore associato alla prima chiave, quindi è quello che faccio anche nella risposta.
doublep,

5
sembra meglio: dict.values().__iter__().__next__():)
Vitaly Zdanevich

17
è fastidioso che dict.keys () non sia direttamente iterabile.
semiomant

3
per un popolo non distruttivo puoi fare una copia (superficiale):key, value = dict(d).popitem()
Pelle

140

Se hai solo bisogno di accedere a un elemento (essendo il primo per caso, poiché i dadi non garantiscono l'ordinamento) puoi semplicemente farlo in Python 2 :

my_dict.keys()[0]     -> key of "first" element
my_dict.values()[0]   -> value of "first" element
my_dict.items()[0]    -> (key, value) tuple of "first" element

Si prega di notare che (per quanto ne sappia) Python non garantisce che 2 chiamate successive a nessuno di questi metodi restituiranno l'elenco con lo stesso ordine. Questo non è supportato con Python3.

in Python 3 :

list(my_dict.keys())[0]     -> key of "first" element
list(my_dict.values())[0]   -> value of "first" element
list(my_dict.items())[0]    -> (key, value) tuple of "first" element

90
Funziona solo in Python 2.x, per 3.x devi usarelist(my_dict.keys())[0]
alldayremix

6
Quindi, che classe di complessità è questa? Sicuramente, list(my_dict.keys())[0]non è pigro?
Evgeni Sergeev,

1
Per chiarire, cosa intendeva @alldayremix con quel commento è che i risultati my_dict.function () di Python 3.x non supportano l'indicizzazione, ecco perché prima di tutto dobbiamo convertirlo in un elenco e quindi possiamo usare l'indice [0]
Noki,

57

In python3, Il modo:

dict.keys() 

restituisce un valore nel tipo: dict_keys (), avremo un errore quando avremo il primo membro delle chiavi di dict in questo modo:

dict.keys()[0]
TypeError: 'dict_keys' object does not support indexing

Infine, converto dict.keys () in list @ 1st e ottengo il 1 ° membro con il metodo splice list:

list(dict.keys())[0]

Questa è la soluzione più semplice e funziona sia in python2 che in python3.
mattmilten,

Per i miei soldi. Dico che questa risposta è la più intuitiva
Thomas Valadez,

Sì, ma questo non risponde alla domanda OP, che è come ottenere i VALORI, non le chiavi.
Mike Williamson,

1
@MikeWilliamson si spera che la maggior parte dei lettori sappia come ottenere il valore corrispondente, dato una chiave, da un python dict.
eric

5
Per ottenere un oggetto arbitrario, non una chiave arbitraria, puoi farlo analogamente list(dict.values())[0].
jhin,

24

per ottenere una chiave

next(iter(mydict))

per ottenere un valore

next(iter(mydict.values()))

per ottenere entrambi

next(iter(mydict.items())) # or next(iter(mydict.viewitems())) in python 2

I primi due sono Python 2 e 3. Gli ultimi due sono pigri in Python 3, ma non in Python 2.


16

Come altri hanno già detto, non esiste un "primo elemento", poiché i dizionari non hanno un ordine garantito (sono implementati come tabelle hash). Se vuoi, ad esempio, il valore corrispondente alla chiave più piccola, thedict[min(thedict)]lo farà. Se ti interessa l'ordine in cui sono state inserite le chiavi, vale a dire "primo" intendi "inserito per primo", allora in Python 3.1 puoi usare collection.OrderedDict , che è anche nell'imminente Python 2.7; per le versioni precedenti di Python, scaricare, installare e utilizzare il backport dict ordinato (2.4 e versioni successive) che è possibile trovare qui .

Python 3.7 Ora i dicts sono ordinati per inserzione.


11

Cosa ne pensi di questo. Non ancora menzionato qui.

py 2 e 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2

5
dict.values()restituisce una vista, quindi dovrebbe essere O (1). list(a)restituisce un nuovo elenco, quindi sarebbe O (n).
boycy

Inoltre sembra che non funzioni in python2 se a = {"a": {"1"}}
qasimzee,

11

Ignorando i problemi relativi all'ordinamento dei dict, questo potrebbe essere migliore:

next(dict.itervalues())

In questo modo evitiamo la ricerca degli articoli e generiamo un elenco di chiavi che non utilizziamo.

python3

next(iter(dict.values()))

2
valori () farà una copia di tutti i valori (così come le chiavi () per le chiavi), quindi questo comporterà molte operazioni O (n ^ 2).
Glenn Maynard,

Quindi sarà la versione dei PO? Lo cambierò per usare un iteratore allora.
Matt Joiner,

4
Questo è solo Python 2. Per Python 3, dobbiamo next(iter(dict.values()))ottenere lo stesso risultato senza creare l'elenco.
Kap


2

Puoi sempre fare:

for k in sorted(d.keys()):
    print d[k]

Questo ti darà una serie di chiavi sistemate in modo coerente (rispetto a builtin .hash () immagino) su cui puoi elaborare se l'ordinamento ha qualche significato per te. Ciò significa che, ad esempio, i tipi numerici vengono ordinati in modo coerente anche se si espande il dizionario.

ESEMPIO

# lets create a simple dictionary
d = {1:1, 2:2, 3:3, 4:4, 10:10, 100:100}
print d.keys()
print sorted(d.keys())

# add some other stuff
d['peter'] = 'peter'
d['parker'] = 'parker'
print d.keys()
print sorted(d.keys())

# some more stuff, numeric of different type, this will "mess up" the keys set order
d[0.001] = 0.001
d[3.14] = 'pie'
d[2.71] = 'apple pie'
print d.keys()
print sorted(d.keys())

Si noti che il dizionario viene ordinato quando viene stampato. Ma il set di chiavi è essenzialmente una hashmap!


2

Per entrambi Python 2 e 3:

import six

six.next(six.itervalues(d))

Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti a un autore, lascia un commento sotto il suo post.
Martin Tournoij,

Questo risponde esattamente alla domanda Is there any better way to do this?in breve tempo.
oblalex,

Questa risposta è già stata data due volte, una delle quali è stata su questo sito per quasi 5 anni. Questo è un commento su un'altra risposta (come in: ecco come migliorare la risposta per farla funzionare con Python 2 e 3 ), e non una "nuova" risposta, come tale. Il sistema di recensioni di SO ha automaticamente inserito una nota un po 'inutile in questo caso ...
Martin Tournoij

No signore. Hai aggiunto questa variante alla tua risposta a 5 anni appena 17 ore fa, 1 ora dopo aver scritto questa risposta. Prova a usare 'trova' in questa pagina per la parola 'sei' e troverai solo 6 corrispondenze solo in queste 2 risposte. Comunque, questa risposta ti disturba davvero? Penso che questo potrebbe aiutare altre persone in futuro e questo va bene. Allora, qual è il problema?
oblalex,

Questo perché IMHO questa risposta avrebbe dovuto essere una modifica a quel post in primo luogo. Senza la modifica, le persone dovrebbero scorrere un numero di pagine verso il basso per vedere la tua risposta; pensi che sia più utile che modificare una risposta altamente votata che è quasi esattamente la stessa della tua?
Martin Tournoij,


-1

Nessuna libreria esterna, funziona su Python 2.7 e 3.x:

>>> list(set({"a":1, "b": 2}.values()))[0]
1

Per chiave aribtrary basta tralasciare .values ​​()

>>> list(set({"a":1, "b": 2}))[0]
'a'

-2

La sottoclasse dictè un metodo, sebbene non efficiente. Qui se si fornisce un numero intero, verrà restituito d[list(d)[n]], altrimenti accedere al dizionario come previsto:

class mydict(dict):
    def __getitem__(self, value):
        if isinstance(value, int):
            return self.get(list(self)[value])
        else:
            return self.get(value)

d = mydict({'a': 'hello', 'b': 'this', 'c': 'is', 'd': 'a',
            'e': 'test', 'f': 'dictionary', 'g': 'testing'})

d[0]    # 'hello'
d[1]    # 'this'
d['c']  # 'is'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.