セットからのrandom.choice?Python


94

私は推測ゲームのAI部分に取り組んでいます。AIにこのリストからランダムな文字を選択してもらいたい。私はそれをセットとして行っているので、ゲームで推測された文字をリストから簡単に削除できるため、再度推測することはできなくなります。

setオブジェクトはインデックスに登録できないと表示されます。どうすればこれを回避できますか?

import random 
aiTurn=True

while aiTurn == True:
    allLetters = set(list('abcdefghijklmnopqrstuvwxyz'))
    aiGuess=random.choice(allLetters)



    print (aiGuess) 

1
ちなみに、文字列はそれ自体で反復可能であるため、文字のセットを取得するためにset(list( 'string'))を使用する必要はありません。set( 'abc')は必要な処理を実行します。
スコットリッチー

5
この問題に直面している他の人にとっては、効率的なランダム選択を可能にするセットのようなオブジェクトを作成する方法についてのこの質問を見る価値があります。ここに示されているオプションはすべてO(N)です。 stackoverflow.com/q/15993447/2966723
Joel

回答:


92
>>> random.sample(set('abcdefghijklmnopqrstuvwxyz'), 1)
['f']

ドキュメント:https//docs.python.org/3/library/random.html#random.sample


9
[0]最後にaを付けて、基本的に同じにしますrandom.choice(リストの形式で値を返しません)
Nick T

31
random.sampletuple(population)内部で、そのrandom.choice(tuple(allLetters))方が良いかもしれません。
utapyngo 2014

21
このプロセスはO(N)であることを強調しておく必要があります。
ジョエル

@JoelなぜこのプロセスはO(N)なのですか?
ManuelSchneid3r 2017年

2
本当に非効率的だと思います... github.com/python/cpython/blob/2.7/Lib/random.py#L332-L339を見るとわかるように、サンプル関数は、上記の呼び出しを行うたびにセットからリストを作成します。それからランダムな要素を取ります。大きなセットがあり、たくさんのサンプルを作成したいとします。セットが変更されない場合は、リストに変換してを使用することをお勧めしますrandom.choice。サンプリング中にセットも変更される場合は、おそらくセットをまったく使用しないでください。セット内の占有ハッシュとバケットサイズがわかっている場合は、サンプリング関数を簡単に記述できます...
jakab922 2017年

58

を使用する必要がありますrandom.choice(tuple(myset))。これは、よりも高速で、間違いなく見た目がすっきりしているためrandom.sampleです。私はテストするために以下を書きました:

import random
import timeit

bigset = set(random.uniform(0,10000) for x in range(10000))

def choose():
    random.choice(tuple(bigset))

def sample():
    random.sample(bigset,1)[0]

print("random.choice:", timeit.timeit(choose, setup="global bigset", number=10000)) # 1.1082136780023575
print("random.sample:", timeit.timeit(sample, setup="global bigset", number=10000)) # 1.1889629259821959

数字からすると、random.sample7%長くかかるようです。


2
私のマシンでは、random.choiceは7倍高速です。
noɥʇʎԀʎzɐɹƆ

4
タプルにコピーせずに、セットから直接選択する方法はありませんか?
youda008 2017

5000個の要素のセットで選択するよりも約12%(250ミリ秒)遅いサンプルが得られます。
サイモン

1
私のマシンでrandom.samplerandom.choice、設定サイズが大きくなるにつれて、低速から高速になります(クロスオーバーポイントは設定サイズ100k〜500kの間のどこかにあります)。つまり、セットが大きいほど、random.sample高速になる可能性が高くなります。
jakee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.