2010-11-22 91 views
2

道歉,如果这很简单,但我一直在寻找一段时间,找不到一个简单高效的解决方案。根据搜索条件从Python数组中返回随机元素

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

例如:

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阵列,并且需要做很多次,所以我可以做到尽可能高效。

在此先感谢您的帮助和建议!

+0

你确定你有一个数组?或者它是列表的列表? – 2010-11-22 17:02:54

+0

“很多次”是指在同一个阵列上多次执行,还是针对不同的阵列? – lijie 2010-11-22 17:05:04

+0

对不起,列表。我的错。我会纠正这个帖子。 – Scott 2010-11-22 17:05:43

回答

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)) 
0

当你从random.choice检查您的结果,如果它是你如何想它用正确的元素,如果它再不是随机

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

编辑:避免与re模块混乱,感谢

1

我会用一个NumPy阵列实现这一点:

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

如果你的店你在从一开始就与NumPy阵列数据,这种方法可能比任何你可以用列表的列表做得更快。

如果你想为相同的数据选择许多指标,那么还有更快的方法。

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) 

如果你会做很多次,可能是值得缓存生成的索引列表通过理解,然后从中挑选几次,而不是每次都计算列表理解。

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