道歉,如果这很简单,但我一直在寻找一段时间,找不到简单有效的解决方案。
我有一个列表的二维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阵列执行此操作,并且需要多次执行此操作,因此我可以尽可能高效地执行此操作。
提前感谢您的任何帮助和建议!
答案 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