简体   繁体   English

使用理解创建Python字典

[英]Creating a Python dictionary using a comprehension

I am trying to create a python dictionary with the following values in python 2.7.3: 我试图在python 2.7.3中创建一个python字典,其中包含以下值:

'A':1
'B':2
'C':3
  .
  .
  .
  .
'Z':26

using either of the following lines: 使用以下任一行:

theDict = {x:y for x in map(chr,range(65,91)) for y in range(1,27)}

or 要么

theDict = {x:y for x in map(chr,range(65,91)) for y in list(range(1,27))}

In both cases, I get the following result: 在这两种情况下,我得到以下结果:

'A':26
'B':26
'C':26
  .
  .
  .
  .
'Z':26

I don't understand why the second for is not generating the numbers 1-26. 我不明白为什么第二个没有产生数字1-26。 Maybe it is, but if so, I don't understand why I am only getting 26 for the value of each key. 也许是,但如果是这样,我不明白为什么我只得到26每个键的价值。 If I don't create a dictionary (ie change x:y with just x or y), x = capital letters and y = 1-26. 如果我不创建字典(即只用x或y更改x:y),则x =大写字母,y = 1-26。

Can someone explain what I am doing wrong and suggest a possible approach to get the result that I want. 有人可以解释我做错了什么,并建议一种可能的方法来获得我想要的结果。

Why it's wrong: Your list comprehension is nested. 为什么这是错的:你的列表理解是嵌套的。 It's effectively something like this: 它实际上是这样的:

d = {}
for x in map(chr, range(65, 91)):
    for y in range(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 ie {'A':1, 'B':1, 'C':1, ...} . 它的作用是将y设置为1,然后遍历字母表,将所有字母设置为1,即{'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. 然后它再次为2,3,4,一直到26。因为它是一个字典,后来的设置覆盖了早期的设置,你看到你的结果。

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. zip从每个子列表中提取一个值,并使其成为每次迭代的元组。 In other words, it converts 3 lists of 4 items each, into 4 lists of 3 items each (in the above). 换句话说,它将每个4个项目的3个列表转换为4个列表,每个列表包含3个项目(在上面)。 In your example, you have 2 lists of 26 items, when you want 26 pairs; 在您的示例中,当您需要26对时,您有2个26项列表; zip will do that for you. zip会为你做到这一点。

Try: 尝试:

>>> {chr(k):k-64 for k in range(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: 或者,如果你想做你正在做的事情,请使用zip:

>>> {x:y for x,y in zip(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: 即,在shell中尝试这个:

>>> [(chr(outter), inner) for outter in range(65,91) for inner in range(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 in range(65,91) for inner in range(1,27)])
676

You can see that it is executing 26x26 times (26x26=676) 你可以看到它正在执行26x26次(26x26 = 676)

Since a dict will just update with the new value, the last value for each letter is used: 由于dict将使用新值更新,因此使用每个字母的最后一个值:

>>> 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. 这说明了为什么你得到了你得到的东西。

You can try the following: 您可以尝试以下方法:

theDict = {chr(y):y - 64 for y in range(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}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM