Como indexar em um dicionário?

94

Tenho um dicionário abaixo:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

Como faço para indexar a primeira entrada no dicionário?

colors[0]retornará um KeyErrorpor motivos óbvios.

Harpal
fonte
4
O que significa "primeiro"? Os dicionários não têm ordem.
S.Lott
2
A inserção de dicionários agora foi solicitada desde Python 3.7 Verifique isto: stackoverflow.com/questions/39980323/…
Nikita Alkhovik
1
@ S.Lott, aposto que ele não teria perguntado se soubesse que eles estavam desordenados :).
user7778287

Respostas:

110

Os dicionários não são ordenados nas versões do Python até e incluindo o Python 3.6. Se você não se importar com a ordem das entradas e quiser acessar as chaves ou valores por índice de qualquer maneira, poderá usar d.keys()[i]e d.values()[i]ou d.items()[i]. (Observe que esses métodos criam uma lista de todas as chaves, valores ou itens no Python 2.x. Portanto, se você precisar deles mais de uma vez, armazene a lista em uma variável para melhorar o desempenho.)

Se você se preocupa com a ordem das entradas, começando com Python 2.7, você pode usar collections.OrderedDict. Ou use uma lista de pares

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

se você não precisa de acesso por chave. (Por que seus números são sequências de caracteres?)

No Python 3.7, os dicionários normais são ordenados, então você não precisa OrderedDictmais usar (mas você ainda pode - é basicamente o mesmo tipo). A implementação CPython do Python 3.6 já incluiu essa mudança, mas como não faz parte da especificação da linguagem, você não pode confiar nela no Python 3.6.

Sven Marnach
fonte
2
No Python 2, use em d.iterkeys().next()vez de d.keys()[0]para inspecionar uma das chaves sem removê-la. Se o dicionário for enorme, fará uma grande diferença em termos de desempenho. O mesmo vale para valores e itens. No Python 2.7, você também pode usar objetos de visualização de dict
simleo
42
No Python 3, essas chamadas retornam uma visão, em vez de uma lista real, então você deve envolvê-las em uma chamada para list (), caso contrário, você verá: "TypeError: objeto 'dict_values' não suporta indexação". Veja esta pergunta do SO: stackoverflow.com/questions/17431638/…
stifin
2
Apenas uma pequena correção: você não pode indexar itens (), pelo menos não no Python 3.
John Strong
1
Esta resposta está desatualizada para python 3.6+, consulte a resposta de @Pasha abaixo.
hans
1
@hans Esta resposta está desatualizada para Python 3.7, mas não para Python 3.6, uma vez que a natureza de preservação da ordem dos dicionários é um detalhe da implementação do CPython daquela versão do Python, não uma parte oficial da linguagem. Vou atualizar esta resposta de acordo.
Sven Marnach
105

Se alguém ainda está olhando para esta pergunta, a resposta aceita atualmente está desatualizada:

Como o Python 3.7 * os dicionários preservam a ordem , ou seja, eles agora se comportam exatamente como collections.OrderedDictcostumavam ser. Infelizmente, ainda não há um método dedicado para indexar no keys()/ values()do dicionário, portanto, obter a primeira chave / valor no dicionário pode ser feito como

first_key = list(colors)[0]
first_val = list(colors.values())[0]

ou alternativamente (isso evita instanciar a visualização das chaves em uma lista):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

Se você precisar de uma nchave -th, da mesma forma

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(* CPython 3.6 já incluía dicts ordenados, mas este era apenas um detalhe de implementação. A especificação da linguagem inclui dicts ordenados de 3.7 em diante.)

Paxá
fonte
Pode fornecer o link para a documentação correspondente?
Miind
3

Abordar um elemento do dicionário é como sentar em um burro e aproveitar o passeio.

Como regra do Python, o DICIONÁRIO não tem ordem

Se houver

dic = {1: "a", 2: "aa", 3: "aaa"}

Agora, suponha que se eu gostar dic[10] = "b", então não adicionarei assim sempre

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

Pode ser como

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Ou

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Ou

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Ou qualquer combinação desse tipo.

Portanto, a regra geral é DICIONÁRIO não tem ordem !

Raj Damani
fonte
isso é muito direto ... eu gosto!
Alex Liu 33214
2

Se precisar de um dicionário encomendado, você pode usar odict .

Utku Zihnioglu
fonte
odict não vê suporte para indexação em keys (), values ​​() ou items ().
Konstantin
2

Na verdade, encontrei uma solução nova que realmente me ajudou. Se você estiver especialmente preocupado com o índice de um determinado valor em uma lista ou conjunto de dados, pode apenas definir o valor do dicionário para esse Índice !:

Apenas observe:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Agora, com o poder dos hashmaps, você pode obter o índice de suas entradas em tempo constante (também conhecido como muito mais rápido)

user3368835
fonte
1

oh, essa é difícil. O que você tem aqui, basicamente, são dois valores para cada item. Então você está tentando ligar para eles com um número como chave. Infelizmente, um dos seus valores já está definido como a chave!

Experimente isto:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Agora você pode chamar as chaves por número, como se estivessem indexadas como uma lista. Você também pode fazer referência à cor e ao número por sua posição na lista.

Por exemplo,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

Claro, você terá que descobrir outra maneira de manter o controle da localização de cada cor. Talvez você possa ter outro dicionário que armazene a chave de cada cor como seu valor.

colors_key = {'blue': 1, 'red': 6, 'yllow': 8}

Em seguida, você também poderá pesquisar a chave de cores, se necessário.

colors [colors_key ['blue']] [0] retornará 'blue'

Algo parecido.

E então, enquanto você está nisso, você pode fazer um ditado com os valores numéricos como chaves para que você possa sempre usá-los para pesquisar suas cores, você sabe, se precisar.

valores = {5: [1, 'azul'], 6: [2, 'vermelho'], 8: [3, 'amarelo']}

Então, (cores [cores_chave [valores [5] [1]]] [0]) retornará 'azul'.

Ou você pode usar uma lista de listas.

Boa sorte!

Godfreyluck
fonte
0

Você não pode, pois dictnão está ordenado. você pode usar .popitem()para obter um item arbitrário, mas isso o removerá do dicionário.

Ignacio Vazquez-Abrams
fonte
next(iter(d.items()))( .iteritems()no Python 2) também fornece um item arbitrário (o mesmo em meus testes, o que faz sentido, já que popitem pode ser implementado usando isso), mas não remove o item.