簡體   English   中英

如何在python中的列表理解中編寫以下內容

[英]How to write the following in list comprehension in python

我可以在python中以列表理解方式編寫以下內容嗎

for row in candidates:
    sum=0
    for i in range(1,len(candidates)):
        if(row[i]!='NA')
            sum+=int(row[i])
    row.append(sum)

這里的candidatescandidates列表,其中每個內部列表包含候選項標記。 我想做的是

“我正在增加每個內部列表中的成員,這將保留每個候選人的總分”,例如candidate=[[143050023,5,7,6,8],[14305678,3,4,5,6]] (0內部的索引具有候選的滾動編號)

我想作為

[[143050023,5,7,6,8,26],[14305678,3,4,5,6,18]]

我可以在不使用列表推導的情況下執行相同的操作,但是在嘗試使用列表推導時會遇到困難。我在編寫時面臨的困難是如何對值求和並將其附加到每個內部循環之后的行中。

與普通for循環結構相比,使用列表理解時更好嗎?

讓我們從最后一個問題開始:

與普通for循環結構相比,使用列表理解時更好嗎?

必須做兩件事:

  • 循環的目的是建立一個列表。
  • 作為一種理解,它比作為一個顯式循環更易讀。

注意,您有兩個嵌套循環。 可能可以轉換為具有兩個for子句的理解, 可以轉換為嵌套的理解,但不會轉換為單個平面的理解。

您的內部循環有一個問題:理解不應嘗試對任何事物進行變異, 也不能通過賦值或其他語句對任何事物進行變異。 因此,您需要找到一種重寫它的方法,以使其一成不變地完成工作。

在這種情況下,顯而易見的答案是創建要求和的值,然后將所得的可迭代值傳遞給求和值的函數,例如內置的sum函數:

sum(int(row[i]) for i in range(1, len(row)) if row[i] != 'NA')

我使用了生成器表達式而不是列表推導,因為我們除了循環之外實際上不需要列表。

請注意,您可以進一步簡化此操作。 您唯一使用過的i是在(重復的)表達式row[i] 那么,當您可以直接遍歷行時,為什么要遍歷索引范圍呢?

sum(int(value) for value in row if value != 'NA')

您的外部循環有一個類似的問題:您試圖使循環中的每一row發生變異,而不是建立新的結構。 而且很難想出一個好的替代方案,而是通過構建一個新結構來完成同一件事。

當然,您總是可以分兩步進行操作:

sums = [sum(int(row[i]) for i in range(1, len(candidates)) if row[i] != 'NA')
        for row in candidates]
candidates[:] = [row + [sum] for row, sum in zip(candidates, sums)]

您可以通過再次將sums更改為生成器表達式而不是列表推導來將這兩個遍折疊為一,甚至可以通過就地執行而不使用命名的臨時變量將其轉換為單行:

candidates[:] = [row + [total] for row, total in zip(candidates, (sum(
    int(row[i]) for i in range(1, len(candidates)) if row[i] != 'NA')
    for row in candidates))]

但是,很難說它比原始版本更具可讀性,甚至與可讀性幾乎接近。

另外,請注意,我調用了一個變量,該變量保存每個sum total ,而不是sum sum函數是Python中一個非常重要的內置函數(我們在此答案中實際上正在使用一個函數),因此通過創建同名變量來隱藏它是一個壞主意。 即使在這種情況下,它僅存在於不使用內置函數的列表理解范圍內,因此它對於解釋器而言並不歧義,但對於人類讀者而言仍然是歧義且令人困惑。 (感謝Padraic Cunningham指出了這一點。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM