Acessando elementos do dicionário Python por índice

117

Considere um ditado como

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

Como faço para acessar, por exemplo, um determinado elemento deste dicionário? por exemplo, gostaria de imprimir o primeiro elemento após alguma formatação do primeiro elemento da Apple que, em nosso caso, é apenas 'americano'?

Informações adicionais A estrutura de dados acima foi criada analisando um arquivo de entrada em uma função Python. Uma vez criado, no entanto, ele permanece o mesmo para aquela execução.

Estou usando essa estrutura de dados em minha função.

Portanto, se o arquivo for alterado, da próxima vez que este aplicativo for executado, o conteúdo do arquivo será diferente e, portanto, o conteúdo desta estrutura de dados será diferente, mas o formato será o mesmo. Então, veja, em minha função, não sei se o primeiro elemento na Apple é 'americano' ou qualquer outra coisa, então não posso usar 'americano' diretamente como uma chave.

alessandra
fonte
2
Você pode dar um exemplo da saída que você espera?
Björn Pollex
3
O que você realmente deseja fazer com essa estrutura? E você conhece as chaves do dict ('Apple' e 'Grapes' no seu exemplo)? Ou você só sabe que vai receber um ditado?
juanchopanza
6
Não chame seu dicionário dict. A palavra 'dict' já é uma palavra-chave em Python. Use outra coisa, como mydict.
Rick apoia Monica em
Nota: Esta questão é sobre como acessar os elementos dict por índice , o que não faz sentido porque dicts não são ordenados. Para uma pergunta sobre como acessar elementos em um dicionário aninhado, consulte Python - acessando valores aninhados em dicionários .
Aran-Fey,
@ Aran-Fey: as coisas não ordenadas têm uma ordem intrínseca. Não pedido! = Sem pedido.
Jamie Marshall

Respostas:

122

Por se tratar de um dicionário, você acessa através das teclas. Armazenando o dicionário em "Apple", faça o seguinte:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

E pegando quantos deles são americanos (16), faça assim:

>>> mydict["Apple"]["American"]
'16'
Morten Kristensen
fonte
9
Como fazer isso dinamicamente sem conhecer a profundidade dos elementos?
Ethan Bierlein
3
O que exatamente você gostaria de saber? Você pode obter as chaves de um dicionário .keys()para acessá-las dinamicamente.
Morten Kristensen
3
Como, por exemplo, se você tivesse um dicionário de profundidade desconhecida, por exemplo, um dicionário aninhado, e você tem um elemento "n"em uma profundidade desconhecida, armazenado em um elemento desconhecido.
Ethan Bierlein
1
Essa é uma questão muito ampla. Dada sua estrutura de dados, você escreveria uma função ou classe para manipulá-la apropriadamente. Talvez você possa fornecer uma chave e uma estratégia para tentar encontrar a chave.
Morten Kristensen
1
@EthanBierlein use: 'for key, value in dictionary.iteritems ()' para ter acesso à chave e ao valor
danius
25

Se a pergunta for, se eu sei que tenho um ditado que contém 'Maçã' como uma fruta e 'Americano' como um tipo de maçã, eu usaria:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

como outros sugeriram. Se, em vez disso, a pergunta for: você não sabe se 'Apple' como uma fruta e 'American' como um tipo de 'Apple' existem quando você lê um arquivo arbitrário em sua estrutura de dados dict, você poderia fazer algo como:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

ou melhor ainda, para que você não itere desnecessariamente sobre todos os ditos se souber que apenas a Apple tem o tipo americano:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

Em todos esses casos, não importa a ordem em que os dicionários realmente armazenam as entradas. Se você estiver realmente preocupado com o pedido, considere usar OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict

JoshAdel
fonte
20

Como notei sua descrição, você só sabe que seu analisador lhe dará um dicionário que seus valores também são dicionários assim:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

Portanto, você deve iterar em seu dicionário pai. Se você deseja imprimir ou acessar todas as primeiras chaves do dicionário na sampleDict.values()lista, você pode usar algo assim:

for key, value in sampleDict.items():
    print value.keys()[0]

Se você deseja acessar apenas a primeira chave do primeiro item sampleDict.values(), isso pode ser útil:

print sampleDict.values()[0].keys()[0]

Se você usar o exemplo que deu na pergunta, quero dizer:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

A saída para o primeiro código é:

American
Indian

E a saída para o segundo código é:

American
Zeinab Abbasimazar
fonte
10

Como bônus, gostaria de oferecer uma solução diferente para o seu problema. Você parece estar lidando com dicionários aninhados, o que geralmente é tedioso, especialmente quando você precisa verificar a existência de uma chave interna.

Existem algumas bibliotecas interessantes sobre isso no pypi, aqui está uma busca rápida para você.

No seu caso específico, dict_digger parece adequado.

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None
Flavian Hautbois
fonte
8

Você pode usar dict['Apple'].keys()[0]para obter a primeira chave do Appledicionário, mas não há garantia de que será American. A ordem das chaves em um dicionário pode mudar dependendo do conteúdo do dicionário e da ordem em que as chaves foram adicionadas.

Gabe
fonte
a menos que você use OrderedDictna collectionsbiblioteca
Escachator
7

Eu sei que tenho 8 anos, mas parece que ninguém realmente leu e respondeu à pergunta.

Você pode chamar .values ​​() em um dict para obter uma lista dos dicts internos e, assim, acessá-los por índice.

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']
Jamie Marshall
fonte
2
interessante, eu tentei isso e consegui 'dict_values' object does not support indexing . Acho que esta resposta precisa de uma atualização, já que você precisa envolver dict_values ​​para recuperar uma lista
Yuca
1
@Yucca - Você estava certo, não testei meu código. A resposta foi atualizada
Jamie Marshall
2

Exemplo simples para entender como acessar os elementos do dicionário: -

Crie um dicionário

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

Explore mais sobre os dicionários Python e aprenda interativamente aqui ...

Manish Methani
fonte
0

Poucas pessoas parecem, apesar das muitas respostas a esta pergunta, ter apontado que os dicionários são mapeamentos não ordenados, e assim (até a bênção da ordem de inserção com Python 3.7) a ideia da "primeira" entrada em um dicionário feito literalmente não faz sentido. E mesmo um OrderedDictsó pode ser acessado por índice numérico usando feiúras como mydict[mydict.keys()[0]](Python 2 apenas, já que em Python 3 keys()é um iterador não subscritível.)

Do 3.7 em diante e na prática também do 3.6 - o novo comportamento foi introduzido então, mas não incluído como parte da especificação da linguagem até o 3.7 - iteração sobre as chaves, valores ou itens de um dicionário (e, eu acredito, um definido também) produzirá primeiro os objetos inseridos menos recentemente. Ainda não existe uma maneira simples de acessá-los por índice numérico de inserção.

Quanto à questão de selecionar e "formatar" itens, se você souber a chave que deseja recuperar no dicionário, normalmente utilizaria a chave como um subscrito para recuperá-la ( my_var = mydict['Apple']).

Se você realmente deseja indexar os itens pelo número da entrada (ignorando o fato de que o número de uma entrada em particular mudará conforme as inserções são feitas), então a estrutura apropriada provavelmente seria uma lista de tuplas de dois elementos. Ao invés de

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

você pode usar:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

Sob esse regime, a primeira entrada está mylist[0]na forma clássica com terminação de lista e seu valor é ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Você pode iterar em toda a lista da seguinte maneira:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

mas se você sabe que está procurando a chave "Apple", por que não usar um dict?

Você poderia introduzir um nível adicional de indireção armazenando em cache a lista de chaves, mas as complexidades de manter duas estruturas de dados em sincronização inevitavelmente aumentariam a complexidade de seu código.

Holdenweb
fonte
0

Com a seguinte função pequena, cavar em um dicionário em forma de árvore se torna muito fácil:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

Agora, dig(mydict, "Apple.Mexican")retorna 10, enquanto dig(mydict, "Grape")produz a subárvore {'Arabian':'25','Indian':'20'}. Se uma chave não estiver contida no dicionário, digretorna None.

Observe que você pode facilmente alterar (ou mesmo parametrizar) o caractere separador de '.' para '/', '|' etc.

Heinrich apóia Monica
fonte