2

これが簡単な場合はお詫びしますが、私はしばらくの間探していて、単純で効率的な解決策を見つけることができません。

1と0のみで構成されるリストの2次元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)を使用してランダムに1つを選択することができますが、これは非常に遅いようで、よりきちんとした、よりPythonicな方法があると感じずにはいられませんこれに近づくために。私はおそらく20x20アレイでこれを実行し、何度も実行する必要があるので、可能な限り効率的に実行できます。

助けとアドバイスを事前に感謝します!

4

5 に答える 5

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))
于 2010-11-22T17:06:50.140 に答える
1

これを実現するには、NumPy配列を使用します。

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

データを最初からNumPy配列に格納する場合、このアプローチは、リストのリストで実行できる方法よりもおそらく高速です。

同じデータに対して多くのインデックスを選択したい場合は、さらに高速なアプローチがあります。

于 2010-11-22T17:18:02.860 に答える
1

random.choiceリストから要素をランダムに選択できるようにするため、リスト内包表記を使用して、要素が1であるインデックスのリストを作成し、ランダムに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)

これを何度も行う場合は、リスト内包を毎回計算するのではなく、内包によって生成されたインデックスのリストをキャッシュして、そこから数回選択する価値があるかもしれません。

于 2010-11-22T17:36:04.097 に答える
0

random.choiceから結果を取得したら、それが再びランダムでない場合は、正しい要素を使用して希望どおりかどうかを確認します

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

編集:reモジュールとの混同を避けるために、ありがとう

于 2010-11-22T17:03:13.107 に答える
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
于 2010-11-22T17:36:16.530 に答える