如何从2D列表中pythonically选择一个随机索引,使相应的元素匹配一个值?

时间:2018-02-05 21:41:49

标签: python python-3.x list random

我有一个二维布尔列表。我想从列表中选择值为False的随机索引。例如,给出以下列表:

[[True, False, False],
 [True, True, True],
 [False, True, True]]

有效选择为:[0, 1][0, 2][2, 0]

我可以保持有效索引列表,然后使用random.choice从中选择,但它似乎unpythonic保持一个变量,每次更新它只有这一个目的基础列表的变化。

如果您的答案很快就会获得奖励积分。

3 个答案:

答案 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,尽管有点在这种情况下是多余的。