【问题标题】:Translating from numpy to pure python从 numpy 转换为纯 python
【发布时间】:2015-03-28 08:03:04
【问题描述】:

我不能使用 numpy,并且我无法将以下内容从 numpy 数组翻译并将特定索引中的值放置到纯 python 仅使用列表和列表方法。有什么建议么?列列表是我需要附加到的列的索引。

n = 15
board = np.array([['1'] * n] * n)

for index in zero.columns: #This is the line im having trouble with
    board[zero.columns.index(index), index] = "0"

ex of zero.columns:[0, 2, 4, 1, 9, 11, 13, 3, 12, 8, 5, 14, 6, 10, 7]

所以带有 numpy 的 htis 的输出将是

[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 

15 x 15 董事会等等。

【问题讨论】:

  • 你想用这段代码做什么?你能展示一个示例输入和预期输出吗?
  • 当然,我会在尝试实现 nqueens 算法时更新一下
  • 你想让纯 Python board 成为 1 个字符串的列表吗?如果是这样,你应该在你的问题中特别提到这一点。
  • 更新并没有意识到我在 numpy 数组中有一个额外的中括号,是的,我试图在不使用 numpy 的情况下获得相同的表示,但问题是试图索引以将 0 放在没有 numpy 的正确位置.我只是让 1 任意代表棋盘上没有皇后的空白点可以很容易地使它们成为空白字符串

标签: python list python-3.x numpy


【解决方案1】:

当你想将你的代码从 NumPy 翻译成普通的 python 时,有几个问题:

>>> board = [['1'] * n for _ in range(n)]
>>> zeros = [0, 2, 4, 1, 9, 11, 13, 3, 12, 8, 5, 14, 6, 10, 7]
>>> for row, idx in zip(board, zeros):
...   row[idx] = '0'
... 
>>> pprint.pprint(board)
[['0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '0', '1'],
 ['1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '0'],
 ['1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1'],
 ['1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1']]

最棘手的部分是您需要一个理解列表而不是最简单的[['1']*n]*n 来创建初始板,因为* 运算符实际上会创建对same 对象的重复引用。但是,您确实需要 不同 行。这是一个演示该问题的简单示例:

>>> m = [['1']*3]*2
>>> m[1][2] = '0'   # I might think I changed only *one* cell
>>> m
[['1', '1', '0'], ['1', '1', '0']]
#            ^                ^
# but *two* cells appear to have changed.
>>> m[0] is m[1]
True
# because m[0] and m[1] are in fact referencing the _same_ object.

之后,您需要同时遍历不同的行并通过 zeros 索引。在这里,我为此使用了zip

【讨论】:

  • 虽然它在这里工作,但我不希望在嵌套列表理解中重复使用索引变量:有时能够访问内部列表 comp 中的外部索引很方便。对于int 版本,您可以将板初始化简化为board = [['1']*n for _ in range(n)]board = [[1]*n for _ in range(n)]。这是安全的,因为每个内部列表都是一个新列表。
  • 另外,初始化和设置零可以在单个列表 comp 中完成:board = [[0 if x == zeroes[y] else 1 for x in range(n)] for y in range(n)],但我怀疑您的方式稍微快一些,因为它避免了内部循环中的测试。跨度>
  • @PM2Ring 感谢您的 cmets。两者都完全正确。我已经更新了我的答案以简化初始化。至于“更新循环”——正如您所提到的,具有就地更新的普通旧程序循环通常比列表理解执行得更好。但是在这里,我必须承认,我考虑的更多的是可理解性/可读性,而不是性能。 “过早优化...”
  • 是的,正如我在this Meta post 中所说的那样,可读性比小的性能增强更重要。正如您所说,一个普通的旧 for 循环通常与等效的列表理解一样快(如果不快的话),因此将易于阅读的 for 循环构造转换为列表组合可能会带来可疑的好处.我只是在上面给出了我的例子来表明它可以完成,但我当然不推荐它。 :)
猜你喜欢
  • 2020-03-16
  • 2021-06-19
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 2016-12-24
相关资源
最近更新 更多