suponha que eu tenha quantidades de frutas de cores diferentes, por exemplo, 24 bananas azuis, 12 maçãs verdes, 0 morangos azuis e assim por diante. Eu gostaria de organizá-los em uma estrutura de dados em Python que permite fácil seleção e classificação. Minha ideia era colocá-los em um dicionário com tuplas como chaves, por exemplo,
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
ou mesmo dicionários, por exemplo,
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
Gostaria de recuperar uma lista de todas as frutas azuis, ou bananas de todas as cores, por exemplo, ou classificar este dicionário pelo nome da fruta. Existem maneiras de fazer isso de maneira limpa?
Pode ser que dicionários com tuplas como chaves não sejam a maneira adequada de lidar com essa situação.
Todas as sugestões são bem-vindas!
Respostas:
Pessoalmente, uma das coisas que adoro em python é a combinação tupla-dicionário. O que você tem aqui é efetivamente um array 2d (onde x = nome da fruta ey = cor), e geralmente sou um defensor do ditado de tuplas para implementar arrays 2d, pelo menos quando algo como
numpy
um banco de dados não é mais apropriado . Resumindo, acho que você tem uma boa abordagem.Observe que você não pode usar dicts como chaves em um dict sem fazer algum trabalho extra, então essa não é uma solução muito boa.
Dito isso, você também deve considerar namedtuple () . Dessa forma, você pode fazer isso:
Agora você pode usar seu ditado de contagem de frutas:
Outros truques:
Ecoando chmullig, para obter uma lista de todas as cores de uma fruta, você teria que filtrar as chaves, ou seja,
fonte
name='banana'
?bananas = filter(lambda fruit: fruit.name=='banana', fruits)
ou seja, oubananas = [fruit for fruit in fruits if fruit.name=='banana']
. Essa é uma maneira pela qual dicts aninhados são potencialmente mais eficientes; tudo se resume à maneira como você planeja usar os dados.count
Sua melhor opção será criar uma estrutura de dados simples para modelar o que você tem. Em seguida, você pode armazenar esses objetos em uma lista simples e classificá-los / recuperá-los da maneira que desejar.
Para este caso, eu usaria a seguinte classe:
Em seguida, você pode simplesmente construir instâncias de "Fruit" e adicioná-las a uma lista, conforme mostrado da seguinte maneira:
A lista simples
fruits
será muito mais fácil, menos confusa e com melhor manutenção.Alguns exemplos de uso:
Todas as saídas abaixo são o resultado após a execução do snippet de código fornecido seguido por:
Lista não classificada:
Monitores:
Classificados em ordem alfabética por nome:
Monitores:
Ordenado por quantidade:
Monitores:
Onde cor == vermelho:
Monitores:
fonte
Banco de dados, dicionário de dictes, dicionário de lista de dicionários, denominado tupla (é uma subclasse), sqlite, redundância ... Não acreditei nos meus olhos. O quê mais ?
sim! eu pensei
Então, na minha opinião, uma lista de tuplas é suficiente:
resultado
fonte
Provavelmente, um dicionário não é o que você deveria usar neste caso. Uma biblioteca com mais recursos seria uma alternativa melhor. Provavelmente um banco de dados real. O mais fácil seria sqlite . Você pode manter tudo na memória passando a string ': memory:' em vez de um nome de arquivo.
Se você quiser continuar por este caminho, poderá fazê-lo com os atributos extras na chave ou no valor. No entanto, um dicionário não pode ser a chave para outro dicionário, mas uma tupla pode. Os documentos explicam o que é permitido. Deve ser um objeto imutável, que inclui strings, números e tuplas que contêm apenas strings e números (e mais tuplas contendo apenas esses tipos recursivamente ...).
Você poderia fazer seu primeiro exemplo com
d = {('apple', 'red') : 4}
, mas será muito difícil consultar o que deseja. Você precisaria fazer algo assim:fonte
Com chaves como tuplas, basta filtrar as chaves com determinado segundo componente e classificá-lo:
A classificação funciona porque as tuplas têm ordem natural se seus componentes têm ordem natural.
Com as chaves como objetos completos, basta filtrar
k.color == 'blue'
.Você realmente não pode usar dicts como chaves, mas pode criar uma classe mais simples como
class Foo(object): pass
e adicionar quaisquer atributos a ela instantaneamente:Essas instâncias podem servir como chaves de ditado, mas cuidado com sua mutabilidade!
fonte
Você pode ter um dicionário onde as entradas são uma lista de outros dicionários:
Resultado:
Edit: Como eumiro apontou, você poderia usar um dicionário de dicionários:
Resultado:
fonte
Este tipo de dados é extraído com eficiência de uma estrutura de dados do tipo Trie. Também permite uma classificação rápida. A eficiência da memória pode não ser tão grande.
Um trie tradicional armazena cada letra de uma palavra como um nó na árvore. Mas no seu caso, o seu "alfabeto" é diferente. Você está armazenando strings em vez de caracteres.
pode ser parecido com isto:
veja este link: trie em python
fonte
Você deseja usar duas chaves independentemente, então você tem duas opções:
Armazene os dados de forma redundante com dois dicts como
{'banana' : {'blue' : 4, ...}, .... }
e{'blue': {'banana':4, ...} ...}
. Então, pesquisar e classificar é fácil, mas você deve certificar-se de modificar os dictos juntos.Armazene apenas um dicionário e, em seguida, escreva funções que iterem sobre eles, por exemplo:
fonte