[英]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.