setten random.choice? piton


94

Bir tahmin oyununun yapay zeka bölümü üzerinde çalışıyorum. Yapay zekanın bu listeden rastgele bir harf seçmesini istiyorum. Bunu bir set olarak yapıyorum, böylece oyunda tahmin edilen harfleri listeden kolayca çıkarabiliyorum ve bu nedenle artık tekrar tahmin edilemiyor.

setnesnenin indekslenebilir olmadığını söylüyor . Bunu nasıl aşabilirim?

import random 
aiTurn=True

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



    print (aiGuess) 

1
Bu arada, dizeler kendiliğinden yinelenebildiği için bir dizi harf elde etmek için set (list ('string')) kullanmanıza gerek yoktur - set ('abc') istediğinizi yapacaktır.
Scott Ritchie

5
Bu problemle karşılaşan diğerleri için, verimli rastgele seçime izin veren küme benzeri bir nesnenin nasıl oluşturulacağı hakkındaki bu soruya bakmaya değer. Burada verilen seçeneklerin tümü O (N). stackoverflow.com/q/15993447/2966723
Joel

Yanıtlar:


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

Belgeler: https://docs.python.org/3/library/random.html#random.sample


9
[0]Sonunda bir işaretleyin , böylece temelde aynıdır random.choice(bu, değerlerini bir liste biçiminde döndürmez)
Nick T

31
random.sampletuple(population)dahili olarak yapar , bu nedenle random.choice(tuple(allLetters))daha iyi olabilir.
utapyngo

21
Bu işlemin O (N) olduğu vurgulanmalıdır.
Joel

@Joel Bu süreç neden O (N)?
ManuelSchneid3r

2
Gerçekten verimsiz olduğunu düşünüyorum ... github.com/python/cpython/blob/2.7/Lib/random.py#L332-L339'u görebileceğiniz gibi , örnek fonksiyon yukarıdaki çağrıyı her yaptığınızda setten bir liste oluşturur ve ondan rastgele bir öğe alır. Diyelim ki büyük bir setiniz var ve çok sayıda numune yapmak istiyorsunuz. Set değişmezse, onu bir listeye dönüştürmek ve kullanmak daha iyidir random.choice. Set, siz onu örneklerken de değişirse, muhtemelen bir set kullanmamalısınız. Sette işgal edilen hash'leri ve kova boyutlarını biliyorsanız, bir örnekleme işlevi yazmak kolay olurdu ...
jakab922

58

Kullanmalısınız random.choice(tuple(myset)), çünkü daha hızlı ve tartışmasız daha temiz görünüyor random.sample. Test etmek için şunları yazdım:

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

Rakamlardan random.sample% 7 daha uzun sürdüğü görülüyor .


2
Benim makinemde random.choice 7 kat daha hızlı.
noɥʇʎԀʎzɐɹƆ

4
Tuple'a kopyalamak zorunda kalmadan doğrudan setten seçim yapmanın bir yolu yok mu?
Youda008

5000 elementlik bir sette seçilenden yaklaşık% 12 (250 ms) daha yavaş bir örnek alıyorum.
Simon

1
Benim makinede random.sampledaha yavaş olmaktan gider random.choiceseti boyutu büyüdükçe o (çaprazlama noktası belirlendi boyutu 100k-500k arasında bir yerde olduğu) daha hızlı olmasının. Yani, set ne kadar büyükse, daha random.samplehızlı olma olasılığı da o kadar yüksektir .
jakee
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.