簡體   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