繁体   English   中英

美丽的for循环嵌套在dict函数中:这是如何工作的?

[英]beautiful for loop nested in the dict function : how does that work?

我目前正在回顾这篇关于Python中的数独求解器的帖子 我试图逐行解构它,我经历了以下几点

digits   = '123456789'
rows     = 'ABCDEFGHI'
cols     = digits
#squares will give you all the squares of a Sudoku, from A1-A9 to I1-I9
squares  = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])

#each square has 3 units : the row it is in, the column it is in, and the "block" of 3x3 squares it is in :

units = dict((s, [u for u in unitlist if s in u]) 
             for s in squares)

最后一部分让我感到茫然。 如果我没有弄错的话,我们有一个列表理解,在发电机内部。 但是在dict函数中做什么是“for s in square”? 为什么我不能写下面的内容并获得相同的结果?

for s in squares :
    units3 = dict((s, [u for u in unitlist if s in u]))

这对我来说似乎非常模糊,不幸的是我所有尝试为此找到一个资源的结果都指向了有关dict创建的基本教程或循环dict值的结果......

你能不能告诉我dict函数中的for循环是如何工作的,还是指向一个关于该主题的好tuto?

它不是列表理解,而是生成器表达式。 这两者是相关的,但没有建立列表。 生成器表达式生成一个生成器对象,可以在懒惰的情况下迭代,并且每一步都执行循环表达式。

例如,您可以创建这样的表达式来计算方块:

>>> squares = (i ** 2 for i in range(10))
>>> squares
<generator object <genexpr> at 0x10c832468>
>>> next(squares)
0
>>> next(squares)
1
>>> next(squares)
4

next()函数使迭代器前进以产生下一个值。 在两者之间,生成器暂停,剩余的值尚未计算。

在您找到的示例中,生成器表达式是dict()调用的唯一参数,在这种情况下,可以省略生成器表达式的(...) 你也可以写dict((...)) ,它会产生完全相同的结果; 如果一个调用需要多个参数,那么将需要这些括号。 嵌套在dict(...)生成器表达式中只是字典值的列表解析。

生成器生成(key, value)元组, dict() callable用它来创建字典。 请参阅dict()文档

[...]否则,位置参数必须是可迭代对象。 iterable中的每个项目本身都必须是具有两个对象的可迭代项。 每个项目的第一个对象成为新词典中的一个键,第二个对象成为相应的值。

因此,相当于for循环语句应该是:

units = {}
for s in squares:
    units[s] = [u for u in unitlist if s in u]

注意[u for u in unitlist if s in u] list comprehension; 它是一个独立于生成器表达式的独立表达式(但它每次都使用s的当前值)。 循环在我们必须在此处创建的字典中设置一个值,但是否则每个可迭代步骤具有相同的结果:使用列表推导结果作为值设置键s

在Python 2.7和Python 3中,您可以使用字典理解来生成完全相同的字典,而不是生成器表达式:

units = {s: [u for u in unitlist if s in u] for s in squares}

字典理解的模式是{<key expression>: <value expression> for ... in ... <optionally more if filters and for loops>} ; 将其与dict((<key expression>, <value expression>) for ... in ... <optionally more if filters and for loops>)模式使用您找到的代码。 字典理解更快,因为解释器不再需要担心如何在每一步停止和启动生成器表达式,也不必定位dict名称并调用它。

暂无
暂无

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

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