2010-11-22 92 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