[Tutor] Dictionary Comprehensions

Hugo Arts hugo.yoshi at gmail.com
Fri Dec 4 22:01:22 CET 2009

```On Fri, Dec 4, 2009 at 9:32 PM, Khalid Al-Ghamdi <emailkgnow at gmail.com> 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

That dictionary comprehension is equivalent to the following code:

dc = {}
for x in range(6):
for y in list("khalid"):
dc[y] = x

This makes it clear what is wrong. The two for loops come out as
nested, rather than zipped.
The general fix for something like this is the zip function:

bc = {x: y for x, y in zip("khalid", xrange(6))}

However, in this case, the idiomatic way to write this would be the
enumerate function:

bc = {y: x for x, y in enumerate("khalid")}

Note that your output is like so:
{'a': 2, 'd': 5, 'i': 4, 'h': 1, 'k': 0, 'l': 3}

The first character in your original string gets a zero, the second a
one, so on and so forth. I'm hoping that's what you meant. If you
really want this:

{'a': 0, 'd': 1, 'i': 2, 'h': 3, 'k': 4, 'l': 5}

I'm not sure how to do that programmatically. The dict object prints
its objects in no particular order, so figuring out that order is hard
(and very likely implementation/platform dependent). My best guess was
sorted("khalid", key=hash):

{'a': 0, 'd': 1, 'i': 3, 'h': 2, 'k': 4, 'l': 5}

close, but no cigar. Anyone who can think of a clever hack for this?
Not that it's very useful, but fun.

Hugo
```