簡體   English   中英

python流量控制功能怪異

[英]python flow control functioning weird

我正在嘗試使用DP解決背包問題。 基本上,目標是查看列表中是否可以包含某些元素,其總和不超過總和的一半。

def canPartition(nums):
    """
    :type nums: List[int]
    :rtype: bool
    """
    run_sum = 0
    for num in nums:
        run_sum += num

    if run_sum & 1 == 1:
        return False
    run_sum //= 2

    n = len(nums)
    dp = [[False] * (run_sum+1)] * (n+1)

    for i in range(n+1):
        dp[i][0] = True

    for j in range(1, run_sum+1):
        dp[0][j] = False
    print("initial stage")
    print(dp)

    for i in range(1, 2):
        for j in range(1, run_sum+1):
            dp[i][j] = dp[i-1][j]
            print("inner loop after operation 1:")
            print(dp)
            if j >= nums[i-1]:
                print("inner loop after operation 2:")
                print(i, j)
                dp[i][j] |= dp[i-1][(j - nums[i-1])]
                print(dp)
                print(" ")

    return dp[n][run_sum]

nums = [1, 2, 5]
canPartition(nums)

在這里目標本身並不那么重要。 但是最后一個嵌套循環的流控制的行為確實很奇怪。 以下是打印結果。

initial stage
[[True, False, False, False, False], [True, False, False, False, False], [True, False, False, False, False], [True, False, False, False, False]]
inner loop after operation 1:
[[True, False, False, False, False], [True, False, False, False, False], [True, False, False, False, False], [True, False, False, False, False]]
inner loop after operation 2:
1 1
[[True, True, False, False, False], [True, True, False, False, False], [True, True, False, False, False], [True, True, False, False, False]]

inner loop after operation 1:
[[True, True, False, False, False], [True, True, False, False, False], [True, True, False, False, False], [True, True, False, False, False]]
inner loop after operation 2:
1 2
[[True, True, True, False, False], [True, True, True, False, False], [True, True, True, False, False], [True, True, True, False, False]]

inner loop after operation 1:
[[True, True, True, False, False], [True, True, True, False, False], [True, True, True, False, False], [True, True, True, False, False]]
inner loop after operation 2:
1 3
[[True, True, True, True, False], [True, True, True, True, False], [True, True, True, True, False], [True, True, True, True, False]]

inner loop after operation 1:
[[True, True, True, True, False], [True, True, True, True, False], [True, True, True, True, False], [True, True, True, True, False]]
inner loop after operation 2:
1 4
[[True, True, True, True, True], [True, True, True, True, True], [True, True, True, True, True], [True, True, True, True, True]]

您可以看到,即使對於整個嵌套循環,i的值也為1,以某種方式在循環中修改了dp [i> 1]的值。 甚至j從1到4也被修改了。 就像循環中還有另一個“ for range()中的i”一樣。 有誰知道為什么會這樣? 我用python 3.6.1運行了代碼

這條線

dp = [[False] * (run_sum+1)] * (n+1)

創建一個對False 相同列表的n + 1引用的列表。 一個簡單的例子:

>>> x = [[False]]*3
>>> x
[[False], [False], [False]]
>>> x[0][0] = True
>>> x
[[True], [True], [True]]

您幾乎永遠都不想在列表中使用* 使用列表推導來獲取獨立列表:

dp = [[False for _ in range(run_sum+1)] for _ in range(n+1)]

在這條線

 dp = [[False] * (run_sum+1)] * (n+1)

* (n+1)不會神奇地創建內部列表的副本。 相反,它只是將(n+1)引用的列表做成一個列表。

暫無
暫無

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

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