根据搜索条件从Python数组中返回随机元素

时间:2010-11-22 16:58:58

标签: python arrays search indices

道歉,如果这很简单,但我一直在寻找一段时间,找不到简单有效的解决方案。

我有一个列表的二维Python列表,它只包含1和0。

e.g:

a=[[0,1,0],[0,1,1],[1,0,1]]

我希望随机返回一个随机元素的索引= 1.在这种情况下,我想返回:

[0,1], [1,1], [1,2], [2,0], or [2,2]

概率相等。

我可以遍历结构中的每个元素并编译一个符合条件的索引列表,然后使用random.choice(list)随机选择一个 - 但这看起来很慢,我不禁觉得有一个整洁的,更多Pythonic方法来解决这个问题。我将为这个20x20阵列执行此操作,并且需要多次执行此操作,因此我可以尽可能高效地执行此操作。

提前感谢您的任何帮助和建议!

5 个答案:

答案 0 :(得分:2)

我使用列表推导来生成元组列表(位置为1),然后是random.choice:

from random import choice

a = [[0,1,0],[0,1,1],[1,0,1]]
mylist = []

[[mylist.append((i,j)) for j, x in enumerate(v) if x == 1] for i, v in enumerate(a)]
print(choice(mylist))

答案 1 :(得分:1)

我会使用NumPy数组来实现这一目标:

from numpy import array
random_index = tuple(random.choice(array(array(a).nonzero()).T))

如果您从一开始就将数据存储在NumPy数组中,这种方法可能比使用列表列表所做的任何操作都要快。

如果你想为同一数据选择多个指数,那么有更快的方法。

答案 2 :(得分:1)

random.choice允许我们从列表中随机选择一个元素,因此我们只需要使用列表推导来创建元素为1的索引列表,然后随机选择一个。

我们可以使用以下列表理解:

>>> a = [[0,1,0],[0,1,1],[1,0,1]]
>>> [(x,y) for x in range(len(a)) for y in range(len(a[x])) if a[x][y] == 1]
[(0, 1), (1, 1), (1, 2), (2, 0), (2, 2)]

这意味着我们可以做到:

>>> import random
>>> random.choice([(x,y) for x in range(len(a)) for y in range(len(a[x])) if a[x][y] == 1])
(1, 1)

如果您多次这样做,可能值得缓存理解所生成的索引列表,然后多次从中挑选,而不是每次都计算列表理解。

答案 3 :(得分:0)

当你从random.choice获得你的结果时,如果它不是随机的话,检查它是否是你想要的正确元素

def return_random(li):
    item = random.choice(li)
    if item == 1: #insert check here
        return item
    else:
        return_random(li)

编辑:为避免与re模块混淆,谢谢

答案 4 :(得分:0)

另一个想法是以完全不同的方式存储数据:使用一组表示1的条目的索引对而不是列表列表。在您的示例中,这将是

s = set((0, 1), (1, 1), (1, 2), (2, 0), (2, 2))

要随机选择索引对,请使用

random.choice(list(s))

要将条目设置为1,请使用

s.add((i, j))

要将条目设置为0,请使用

s.remove((i, j))

要翻转条目,请使用

s.symmetric_difference_update([(i, j)])

要检查条目是否为1,请使用

(i, j) in s