1

I have a list of days and want to create a dictionary that maps first 3 letters of the day to the full name.

I tried:

day=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
daydict = dict()
for d in day:    
    daydict.update({d[:3]:d})

which gives the desirable result but, then I stumbled upon code which seems more clean.

daydict = dict((d[:3],d)for d in day)

I don't understand this syntax. Please explain how dict((d[:3],d)for d in day) works?

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
sudo_dudo
  • 573
  • 1
  • 5
  • 18

3 Answers3

3

Better way to achieve this is via using dict comprehension expression as:

>>> day=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']

>>> {d[:3]:d for d in day}
{'Wed': 'Wednesday', 'Sun': 'Sunday', 'Fri': 'Friday', 'Tue': 'Tuesday', 'Mon': 'Monday', 'Thu': 'Thursday', 'Sat': 'Saturday'}

In your solution, you are creating a list of tuples and then type-casting it to dict. The value returned by the [(d[:3],d) for d in day] (equivalent of list comprehension expression to your generator expression) will be:

[('Mon', 'Monday'), ('Tue', 'Tuesday'), ('Wed', 'Wednesday'), ('Thu', 'Thursday'), ('Fri', 'Friday'), ('Sat', 'Saturday'), ('Sun', 'Sunday')]

Let's say this value is store as my_dict variable. When you will type-cast it to dict, you will get your desired dict object as:

>>> dict(my_dict)
{'Wed': 'Wednesday', 'Sun': 'Sunday', 'Fri': 'Friday', 'Tue': 'Tuesday', 'Mon': 'Monday', 'Thu': 'Thursday', 'Sat': 'Saturday'}
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
2

Here is what it does.

dict((d[:3],d)for d in day)

For every variable in a day as d return tuple with 2 values in it. First value is a [:3] symbols taken from d, and the second value is a `d'. In the end it forms a dictionary from each tuple in the iteration.

more clear

days=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
daydict = dict((day[:3],day)for day in days)
taras
  • 3,579
  • 3
  • 26
  • 27
2

dict accepts a list (more precisely: an iterator) of tuples (which will become the key-value pair) as argument (there are other options to initialize it); this works:

daydict = dict([('Mon', 'Monday'), ('Tue', 'Tuesday'), ('Wed', 'Wednesday'),
                ('Thu', 'Thursday'), ('Fri', 'Friday'), ('Sat', 'Saturday'), 
                ('Sun', 'Sunday')])

what you are writing is the shortcut there: a dict-comprehension (you don't create the full list just an iterator for your key-value pairs; the dict constructor iterates over them on the go.

python now supports a more compact version of this:

daydict = {d[:3]: d for d in day}
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • dictcomp is probably faster than creating from tuples. – Jean-François Fabre Jan 12 '17 at 20:45
  • @Jean-FrançoisFabre: i briefly had a look at the disassembly of both version: the dictcomp version is shorter at least. did not do any benchmarking though... – hiro protagonist Jan 12 '17 at 20:50
  • @Jean-FrançoisFabre How is dictcomp faster than creating tuples? From my understanding thay both are doing the same job. is it because its a generator function ? – sudo_dudo Jan 12 '17 at 20:59
  • 2
    because creating a tuple allocates some memory for the temporary tuple object. dictcomp is more natural if the tuples don't already exist. It's the allocation that's costly, not the part done by the dictionary. – Jean-François Fabre Jan 12 '17 at 20:59
  • Adding to Jean's explanation. Generator expression involves 2 operations. 1. To create a list of tuples. 2. To type-cast the entire list to dict. Where as in dict comprehension you will be creating dict at the first place – Moinuddin Quadri Jan 12 '17 at 21:20