1

我有以下代码:

letters = 'defghijklmno'
K = {letters[i]:(i*i-1) for i in range(len(letters))}

我知道我正在迭代字母的序列变量以及如何计算值,但我对如何将键设置为字符串的单个字符感到困惑。特别是因为我有字母被索引为我的键。基本上,我只是想弄清楚python如何评估这个表达式

4

8 回答 8

3

这种dict理解基本上是以下的同义词:

k = {}
for i in range(len(letters)):
    k[letters[i]] = i*i - 1

不同之处在于它创建了一个新范围而不是使用外部范围:

>>> letters = 'defghijklmno'
>>> K = {letters[i]:(i*i-1) for i in range(len(letters))}
>>> i          # was defined in an inner scope
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
>>> k = {}
>>> for i in range(len(letters)):
...     k[letters[i]] = i*i - 1
... 
>>> i     # still defined!
11
于 2012-12-09T20:16:34.263 回答
3

解释:

>>> letters = 'defghijklmno'
>>> range(len(letters))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

这意味着

>>> [letters[i] for i in range(len(letters))]
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']

同时

>>> [(i*i-1) for i in range(len(letters))]
[-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]

因此,您的字典理解构建了对'd':-1, 'e':0, 'f':3, ...(等)的字典。

于 2012-12-09T20:18:40.520 回答
1

好吧,首先,这是一种相当糟糕的做法。在 Python 中按索引循环是一种非常糟糕的做法(它更慢,而且读起来很糟糕),所以更好的方法是:

letters = 'defghijklmno'
K = {letter: (i*i-1) for i, letter in enumerate(letters)}

这一切都是一个简单的字典理解。当我们遍历一个字符串时,我们会得到组成它的各个字符。我们使用enumerate()内置函数给我们匹配的数字,然后生成一个字典,从字母到数字的平方,减一。

如果您正在为理解本身而苦苦挣扎,它相当于一个 for 循环(除了更快),我建议您观看我的视频以获取完整的解释,其中包含字典理解的示例以及它的表亲(列表/集合理解和生成器表达式)。

于 2012-12-09T20:15:48.323 回答
0

第二行是字典理解。它就像一个普通的列表推导式或生成器表达式,只是它生成键值对,然后用于形成字典。

代码大致相当于

letters = 'defghijklmno'
K = {}
for i in range(len(letters)):
    key = letters[i]
    val = (i*i-1)
    K[key] = val
于 2012-12-09T20:16:33.793 回答
0

您可以将 Dict 理解重写为循环

K = {} # empty dict
for i in range(len(letters)): # i goes from 0 to 11
    K[letters[i]] = i*i-1

所以在你的单次迭代中

K['d'] = -1
K['e'] = 0
K['f'] = 3
# ...

等等。dict 理解只是编写此循环的一种更短(并且在大多数 Python 程序员看来)更优雅的方式。

于 2012-12-09T20:18:19.850 回答
0

为了理解它,它有助于查看发生的事情的各个部分。for i in range(len(letters))循环不会遍历字母的单个字符,而是遍历字符串的 indizes 。那是因为您可以使用它们的索引访问字符串的单个字符。所以letters[0]指的是第一个字符,letters[1]第二个,letters[len(letters)-1]最后一个。

所以,让我们分别看一下字典的键:

>>> [letters[i] for i in range(len(letters))]
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']

因此,您可以按原始顺序单独获取所有字母。

现在,让我们看一下字典的值:

>>> [(i*i-1) for i in range(len(letters))]
[-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]

所以,现在我们既有键又有值;字典理解现在所做的就是将这些键链接到值——按照上面的顺序。

于 2012-12-09T20:18:21.497 回答
0

对于每个ii == 0i == 11(最后一个字母的索引letters),都会将一个条目添加到结果字典中,其中键为letters[i],其关联值为i*i-1。这给出了:

K['d'] == -1
K['e'] == 0
K['f'] == 3

等等。

于 2012-12-09T20:18:50.840 回答
0

您实际上并没有迭代letters本身的字母;相反,您通过从, to , to , ..., to变化来迭代,的长度。随着您的变化,您将创建一个字典条目,其键是 的第一个字母,其值为。lettersi01211iilettersi*i - 1

换句话说,您创建了一个字典,其中的每个条目都包含一个k来自的字母(键) letters,与一个等于k的指数平方减去的值配对1

您可以用简单的英语将字典理解理解为:所有字母(键)的字典,k带有lettersindex i,与 value 配对i*i - 1

于 2012-12-09T20:33:38.843 回答