【问题标题】:How to rewrite values in a list from a for loop in Python?如何从 Python 中的 for 循环重写列表中的值?
【发布时间】:2021-06-29 10:02:52
【问题描述】:

我正在研究数独求解器,我有这个板:

board = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
]

假设我现在只想将每个数字更改为随机数字(1 到 9 之间)。 我试过这个:

for lst in board:
    for num in lst:
        num = random.randint(1, 9)

我认为这只是取零并将它们更改为随机数,但不会将它们写回列表中,因为当我打印列表时它仍然只是零。那么如何才能真正将随机数写回棋盘呢?

对不起,我是新手。我尝试查找它,但我似乎无法正确理解 for 循环...

【问题讨论】:

标签: python list loops for-loop


【解决方案1】:

您没有就地更改board

for i in range(len(board)):
    for j in range(len(board[i])):
        board[i][j] = random.randint(1, 9)

您也可以使用numpy.random.randint() 创建board,它生成介于[low, high) 之间的值,ff 高为None(默认值),然后结果来自[0, low)

import numpy as np
print(np.random.randint(low=1, high=10, size=(9,9)))

"""
[[4 7 3 4 8 9 8 7 1]
 [8 7 1 3 2 8 8 3 2]
 [4 8 5 9 8 8 9 1 3]
 [5 4 8 5 5 9 3 3 6]
 [7 7 4 7 8 7 2 5 1]
 [7 9 8 1 2 6 5 7 3]
 [9 3 4 1 6 3 2 9 3]
 [7 3 5 7 7 1 3 4 3]
 [7 4 3 5 3 8 8 8 6]]
"""

【讨论】:

  • A high=9 不会在任何地方给出值 9,它必须是 high=10
【解决方案2】:

您将num 更改为随机数,而不是实际列表。为此,您需要这样做:

for i in range(len(board)):
    for j in range(len(board[i])):
        board[i][j] = random.randint(1, 9)

为简单起见,我将使用非嵌套循环。 基本上,您正在迭代板,您正在设置 lst = board[current_iteration]。在它的while循环形式中:

#This is just to make my point clear, don't use this, for loops are better most of the times
while i < len(board):
    lst = board[i] #You are setting lst to board[i], then changing lst instead of board[i]
    lst = #Whatever you like
    i += 1

lst 没有连接到board[i],所以改变 lst 不会改变板子。您想要的是连接变量,这可以通过 Pyhton 中的列表或对象实现,但由于速度低且性质复杂,因此不推荐使用。但是你可以很容易地使用 C 指针并为此构建一个奇怪的 C 指针包装器。

Numpy 解决方案:

board = np.random.randint(low=1, high=10, size=[10, 10]) #Don't know how big sudoku board is, assume it's 10 * 10.

【讨论】:

  • while 循环的有趣解决方案,使用它代替嵌套的 for 循环有什么优势吗?我的意思是有没有办法知道这两种方法中哪一种更快/更好?
  • @Vojta 我只使用了 while 循环来展示使用 for 循环时幕后发生的情况。 while 循环通常更快,但您不能将 range() 与 while 循环一起使用,而 range() 是 Python 中唯一让我震惊的速度。它非常快,所以总体而言,因为您可以将 range() 与 for 循环一起使用,它们更快。
  • @Vojta 因为你有一个二维数组,你仍然需要一个嵌套的 while 循环。你最好使用 numpy 来处理这些类型的东西。
  • 我确信 numpy 会做得更好,但我仍处于学习理解基本 Python 函数的阶段。您的回复很有帮助,谢谢!
  • @Vojta 别担心,Numpy 不需要掌握任何东西。我建议你偶尔使用一些基本的 numpy 函数作为快捷方式,但不要使用太多,因为快捷方式会妨碍你练习。即使你无意使用 numpy,它也必须在你的机器上,它是一个极其重要的库,确切地说是最重要的库。
【解决方案3】:

更短的方法是:

board = [random.sample(range(1,10), 9) for _ in board]

【讨论】:

    【解决方案4】:
    for lst in range(len(board)):
    
        for num in range(len(board[lst])):
    
            board[lst][num] = random.randint(1, 9)
    

    【讨论】:

    • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
    【解决方案5】:

    您正在分配一个新变量(命名为 num 就像您的 for 变量一样)。 对于您的任务,您需要有索引。

    使用range(len(x))的最直接的解决方案:

    for row in board: # can iterate over indices here too, but it's unnececssary
        for index in range(len(row)):
            row[index] = random.randint(1, 9)
    

    可以使用更好的方法。要生成带有随机数的新列表,您可以使用列表推导:

    # using '_' as variable since it's unused
    board = [
        [random.randint(1, 9) for _ in range(9)] # row itself
        for _ in range(9) # iterating over rows
    ]
    

    【讨论】:

    • 在两个嵌套循环中使用下划线_ 可能会出现问题。它是一个常见的占位符,但通常仅在给定语句中用于一个目的。否则,很好的答案。
    【解决方案6】:

    试试这个

    for i, lst in enumerate(board):
        for j, num in enumerate(lst):
            board[i][j] = random.randint(1, 9)
    

    我将把它作为一个练习来理解为什么这可以解决将数字分配给列表的问题(尽管不能将每个数字都分配 9 次)

    【讨论】:

      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      • 2014-02-22
      • 2020-11-22
      • 2020-10-18
      • 1970-01-01
      相关资源
      最近更新 更多