我有一个二维布尔列表。我想从列表中选择值为False
的随机索引。例如,给出以下列表:
[[True, False, False],
[True, True, True],
[False, True, True]]
有效选择为:[0, 1]
,[0, 2]
和[2, 0]
。
我可以保持有效索引列表,然后使用random.choice
从中选择,但它似乎unpythonic保持一个变量,每次更新它只有这一个目的基础列表的变化。
如果您的答案很快就会获得奖励积分。
答案 0 :(得分:4)
我们可以使用类似的oneliner:
import numpy as np
from random import choice
choice(np.argwhere(~a))
使用a
布尔数组。
这样做如下:通过使用~a
,我们否定数组的元素。接下来我们使用np.argwhere
来构造一个 k×2 -array:一个数组,其中每一行都有两个元素:对于每个维度,该值使得相应的值具有值{{1} }。
按False
我们选择一个随机行。但是,我们不能直接使用它来访问该元素。我们可以使用choice(..)
构造函数将其强制转换为元组:
tuple(..)
您可以使用以下方法获取元素:
>>> tuple(choice(np.argwhere(~a)))
(2, 0)
但当然,这并不奇怪:
t = tuple(choice(np.argwhere(~a)))
a[t]
答案 1 :(得分:3)
我的非numpy版本:
GROUP BY
与Willem的result = random.choice([
(i,j)
for i in range(len(a))
for j in range(len(a[i]))
if not a[i][j]])
版本一样,这会生成一个有效元组列表并调用np
来选择一个。
或者,如果您不喜欢我random.choice()
,那么这是一个range(len(...))
版本:
enumerate()
答案 2 :(得分:1)
假设你不想使用numpy。
matrix = [[True, False, False],
[True, True, True],
[False, True, True]]
valid_choices = [(i,j) for i, x in enumerate(matrix) for j, y in enumerate(x) if not y]
random.choice(valid_choices)
使用列表推导,您可以更改if条件(if not y
)以满足您的需求。这将返回随机选择的坐标,但可选地,您可以将列表推导(i,j)
的值部分更改为:y
并且它返回false,尽管有点在这种情况下是多余的。