Skip to content Skip to sidebar Skip to footer

Creating A Python Dictionary Using A Comprehension

I am trying to create a python dictionary with the following values in python 2.7.3: 'A':1 'B':2 'C':3 . . . . 'Z':26 using either of the following lines: theDict = {x:y f

Solution 1:

Why it's wrong: Your list comprehension is nested. It's effectively something like this:

d = {}
for x inmap(chr, range(65, 91)):
    for y inrange(1,27):
        d[x] = y

As you can see, this isn't what you want. What it does is set y to 1, then walk through the alphabet, setting all letters to 1 i.e. {'A':1, 'B':1, 'C':1, ...}. Then it does it again for 2,3,4, all the way to 26. Since it's a dict, later settings overwrite earlier settings, and you see your result.

There are several options here, but in general, the solution to iterate over multiple companion lists is a pattern more like this:

[some_expr(a,b,c) for a,b,c in zip((a,list,of,values), (b, list, of, values), (c, list, of values))]

The zip pulls one value from each of the sublists and makes it into a tuple for each iteration. In other words, it converts 3 lists of 4 items each, into 4 lists of 3 items each (in the above). In your example, you have 2 lists of 26 items, when you want 26 pairs; zip will do that for you.

Solution 2:

Try:

>>> {chr(k):k-64for k inrange(65,91)} 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4, 'G': 7, 'F': 6, 'I': 9, 'H': 8, 'K': 11, 'J': 10, 'M': 13, 'L': 12, 'O': 15, 'N': 14, 'Q': 17, 'P': 16, 'S': 19, 'R': 18, 'U': 21, 'T': 20, 'W': 23, 'V': 22, 'Y': 25, 'X': 24, 'Z': 26}

Or, if you want to do what you are doing use zip:

>>> {x:y for x,y inzip(map(chr,range(65,91)),range(1,27))}
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4, 'G': 7, 'F': 6, 'I': 9, 'H': 8, 'K': 11, 'J': 10, 'M': 13, 'L': 12, 'O': 15, 'N': 14, 'Q': 17, 'P': 16, 'S': 19, 'R': 18, 'U': 21, 'T': 20, 'W': 23, 'V': 22, 'Y': 25, 'X': 24, 'Z': 26}

The reason yours is not working, is that your comprehension is executing the inner the outer loop times. ie, try this in the shell:

>>> [(chr(outter), inner) for outter inrange(65,91) for inner inrange(1,27)]
[('A', 1), ('A', 2), ('A', 3), ('A', 4),... ('A', 26),
...
...
('Z', 1), ('Z', 2), ('Z', 3), ('Z', 4), ..., ('Z', 26)]

So if you do:

>>>len([(chr(outter), inner) for outter inrange(65,91) for inner inrange(1,27)])
676

You can see that it is executing 26x26 times (26x26=676)

Since a dict will just update with the new value, the last value for each letter is used:

>>> dict([(chr(outter), inner) for outter in range(65,91) for inner in range(1,27)])
{'A': 26, 'C': 26, 'B': 26, 'E': 26, 'D': 26, 'G': 26, 'F': 26, 'I': 26, 'H': 26, 'K': 26, 'J': 26, 'M': 26, 'L': 26, 'O': 26, 'N': 26, 'Q': 26, 'P': 26, 'S': 26, 'R': 26, 'U': 26, 'T': 26, 'W': 26, 'V': 26, 'Y': 26, 'X': 26, 'Z': 26}

Which shows why you are getting what you are getting.

Solution 3:

You can try the following:

theDict = {chr(y):y - 64for y inrange(65, 91)}
print theDict

Output:

{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4, 'G': 7, 'F': 6, 'I': 9, 'H': 8, 'K': 11, 'J': 10, 'M': 13, 'L': 12, 'O': 15, 'N': 14, 'Q': 17, 'P': 16, 'S': 19, 'R': 18, 'U': 21, 'T': 20, 'W': 23, 'V': 22, 'Y': 25, 'X': 24, 'Z': 26}

Post a Comment for "Creating A Python Dictionary Using A Comprehension"