random.chọn từ bộ? con trăn


94

Tôi đang nghiên cứu phần AI của trò chơi đoán. Tôi muốn AI chọn một chữ cái ngẫu nhiên từ danh sách này. Tôi đang làm nó như một tập hợp để tôi có thể dễ dàng xóa các chữ cái khỏi danh sách khi chúng được đoán trong trò chơi và do đó không còn khả dụng để đoán lại.

nó cho biết setđối tượng không thể lập chỉ mục. Làm thế nào tôi có thể giải quyết vấn đề này?

import random 
aiTurn=True

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



    print (aiGuess) 

1
Ngẫu nhiên bạn không cần sử dụng set (list ('string')) để lấy một tập hợp các chữ cái vì các chuỗi có thể lặp lại bởi chính chúng - set ('abc') sẽ làm những gì bạn muốn.
Scott Ritchie

5
Đối với những người khác gặp phải vấn đề này, bạn nên xem câu hỏi này về cách tạo một đối tượng giống tập hợp cho phép lựa chọn ngẫu nhiên hiệu quả. Các tùy chọn được đưa ra ở đây đều là O (N). stackoverflow.com/q/15993447/2966723
Joel

Câu trả lời:


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

Tài liệu: https://docs.python.org/3/library/random.html#random.sample


9
Đánh dấu [0]vào cuối để nó về cơ bản giống hệt random.choice(không trả về giá trị của nó ở dạng danh sách)
Nick T

31
random.samplehiện tuple(population)nội bộ, vì vậy random.choice(tuple(allLetters))có thể tốt hơn.
utapyngo

21
Cần lưu ý rằng quá trình này là O (N).
Joel

@Joel Tại sao quá trình này là O (N)?
ManuelSchneid3r

2
Tôi nghĩ rằng nó thực sự không hiệu quả ... Như bạn có thể thấy github.com/python/cpython/blob/2.7/Lib/random.py#L332-L339 , hàm mẫu tạo một danh sách từ tập hợp mỗi khi bạn thực hiện lệnh gọi ở trên và lấy một phần tử ngẫu nhiên từ nó. Giả sử bạn có một bộ lớn và bạn muốn làm nhiều mẫu. Nếu tập hợp không thay đổi, tốt hơn là chuyển nó thành danh sách và sử dụng random.choice. Nếu bộ cũng thay đổi trong khi bạn lấy mẫu thì có lẽ bạn hoàn toàn không nên sử dụng bộ. Nếu bạn muốn biết băm chiếm đóng trong tập và xô kích thước nó sẽ được dễ dàng để viết một hàm lấy mẫu ...
jakab922

58

Bạn nên sử dụng random.choice(tuple(myset)), vì nó nhanh hơn và được cho là trông sạch sẽ hơn random.sample. Tôi đã viết như sau để kiểm tra:

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

Từ những con số, có vẻ như random.samplemất 7% lâu hơn.


2
Trên máy của tôi, random.choice nhanh hơn gấp 7 lần.
noɥʇʎԀʎzɐɹƆ

4
Không có cách nào để chọn trực tiếp từ bộ mà không cần phải sao chép nó vào tuple?
Youda008

Tôi nhận được mẫu chậm hơn khoảng 12% (250 mili giây) so với chọn trên một tập hợp 5000 phần tử.
Simon

1
Trên máy của tôi, random.sampletừ chậm hơn random.choicetrở nên nhanh hơn khi kích thước bộ tăng lên (điểm giao nhau nằm ở đâu đó giữa kích thước bộ 100k-500k). Có nghĩa là, bộ càng lớn thì càng có nhiều khả năng random.samplenhanh hơn.
jakee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.