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.