[Tutor] Dictionary Comprehensions

Dave Angel davea at ieee.org
Fri Dec 4 22:44:13 CET 2009


Khalid Al-Ghamdi wrote:
> Hi everyone!
>
> I'm using python 3.1 and I want to to know why is it when I enter the
> following in a dictionary comprehension:
>
>   
>>>> dc={y:x for y in list("khalid") for x in range(6)}
>>>>         
>
> I get the following:
> {'a': 5, 'd': 5, 'i': 5, 'h': 5, 'k': 5, 'l': 5}
>
> instead of the expected:
> {'a': 0, 'd': 1, 'i': 2, 'h': 3, 'k': 4, 'l': 5}
>
> and is there a way to get the target (expected) dictionary using a
> dictionary comprehension.
>
> note that I tried sorted(range(6)) also but to no avail.
>
> thanks
>
>   
You're confused about what two for loops do here.  It's basically a 
doubly-nested loop, with the outer loop iterating from k through d, and 
the inner loop iterating from 0 to 5.  So there are 36 entries in the 
dictionary, but of course the dictionary overwrites all the ones with 
the same key.  For each letter in the outer loop, it iterates through 
all six integers, and settles on 5.

To do what you presumably want, instead of a doubly nested loop you need 
a single loop with a two-tuple for each item, consisting of one letter 
and one digit.

   dc = { y:x for y,x in zip("khalid", range(6)) }

The output for this is:
  {'a': 2, 'd': 5, 'i': 4, 'h': 1, 'k': 0, 'l': 3}

Now, this isn't the same values for each letter as you "expected," but 
I'm not sure how you came up with that particular order.I expect, and 
get, 0 for the first letter 'k' and 1 for the 'h'.  etc.

Perhaps printing out the zip would make it clearer:
    list( zip("khalid", range(6)) )
yields
    [('k', 0), ('h', 1), ('a', 2), ('l', 3), ('i', 4), ('d', 5)]

DaveA



More information about the Tutor mailing list