Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Tuples/dictionaries as keys, select, sort

Suppose I have quantities of fruits of different colors, e.g., 24 blue bananas, 12 green apples, 0 blue strawberries and so on. I'd like to organize them in a data structure in Python that allows for easy selection and sorting. My idea was to put them into a dictionary with tuples as keys, e.g.,

{     ('banana',    'blue' ): 24,     ('apple',     'green'): 12,     ('strawberry','blue' ): 0,     # ... } 

or even dictionaries, e.g.,

{     {'fruit': 'banana',    'color': 'blue' }: 24,     {'fruit': 'apple',     'color': 'green'}: 12,     {'fruit': 'strawberry','color': 'blue' }: 0,     # ... } 

I'd like to retrieve a list of all blue fruit, or bananas of all colors, for example, or to sort this dictionary by the name of the fruit. Are there ways to do this in a clean way?

It might well be that dictionaries with tuples as keys are not the proper way to handle this situation.

All suggestions welcome!

like image 693
Nico Schlömer Avatar asked Feb 02 '11 19:02

Nico Schlömer


People also ask

How do you sort a dictionary of tuples in Python?

In Python to sort a dictionary by tuples, we can use the combination of dict(), sorted(), and lambda() function. In this example dict() method is used to rearrange the elements and reassigns the dictionary by order.

Can tuple be used as dictionary key in Python?

A tuple containing a list cannot be used as a key in a dictionary. Answer: True. A list is mutable. Therefore, a tuple containing a list cannot be used as a key in a dictionary.

Are Python dictionary keys sorted?

python dictionaries are unordered therefore this is sutable for print or assign to str only. But this also sorts the keys of nested objects, which might not be wanted. Note that this only sorts dictionaries, not lists, e.g. dict. keys() will not be sorted because it is a list.

Can we sort a dictionary with keys?

Dictionaries are made up of key: value pairs. Thus, they can be sorted by the keys or by the values.


1 Answers

Personally, one of the things I love about python is the tuple-dict combination. What you have here is effectively a 2d array (where x = fruit name and y = color), and I am generally a supporter of the dict of tuples for implementing 2d arrays, at least when something like numpy or a database isn't more appropriate. So in short, I think you've got a good approach.

Note that you can't use dicts as keys in a dict without doing some extra work, so that's not a very good solution.

That said, you should also consider namedtuple(). That way you could do this:

>>> from collections import namedtuple >>> Fruit = namedtuple("Fruit", ["name", "color"]) >>> f = Fruit(name="banana", color="red") >>> print f Fruit(name='banana', color='red') >>> f.name 'banana' >>> f.color 'red' 

Now you can use your fruitcount dict:

>>> fruitcount = {Fruit("banana", "red"):5} >>> fruitcount[f] 5 

Other tricks:

>>> fruits = fruitcount.keys() >>> fruits.sort() >>> print fruits [Fruit(name='apple', color='green'),   Fruit(name='apple', color='red'),   Fruit(name='banana', color='blue'),   Fruit(name='strawberry', color='blue')] >>> fruits.sort(key=lambda x:x.color) >>> print fruits [Fruit(name='banana', color='blue'),   Fruit(name='strawberry', color='blue'),   Fruit(name='apple', color='green'),   Fruit(name='apple', color='red')] 

Echoing chmullig, to get a list of all colors of one fruit, you would have to filter the keys, i.e.

bananas = [fruit for fruit in fruits if fruit.name=='banana'] 
like image 91
senderle Avatar answered Sep 18 '22 23:09

senderle