Câu trả lời:
Sử dụng random.choice()
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
Đối với các lựa chọn ngẫu nhiên được bảo mật bằng mật mã (ví dụ: để tạo cụm mật khẩu từ danh sách từ), hãy sử dụngsecrets.choice()
import secrets
foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))
secrets
là phiên bản mới trong Python 3.6, trên các phiên bản cũ hơn của Python, bạn có thể sử dụng random.SystemRandom
lớp:
import random
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
random.sample(lst, n)
Nếu bạn muốn chọn ngẫu nhiên nhiều mục trong danh sách hoặc chọn một mục từ một bộ, tôi khuyên bạn nên sử dụng random.sample
thay thế.
import random
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
Nếu bạn chỉ lấy một mục duy nhất từ danh sách, thì sự lựa chọn sẽ ít rắc rối hơn, vì sử dụng mẫu sẽ có cú pháp random.sample(some_list, 1)[0]
thay vì random.choice(some_list)
.
Thật không may, sự lựa chọn chỉ hoạt động cho một đầu ra duy nhất từ các chuỗi (chẳng hạn như danh sách hoặc bộ dữ liệu). Mặc dù random.choice(tuple(some_set))
có thể là một tùy chọn để nhận một mục duy nhất từ một bộ.
EDIT: Sử dụng bí mật
Như nhiều người đã chỉ ra, nếu bạn yêu cầu các mẫu giả ngẫu nhiên an toàn hơn, bạn nên sử dụng mô-đun bí mật:
import secrets # imports secure module.
secure_random = secrets.SystemRandom() # creates a secure random object.
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = secure_random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
EDIT: Pythonic One-liner
Nếu bạn muốn có một lớp lót pythonic hơn để chọn nhiều mục, bạn có thể sử dụng giải nén.
import random
first_random_item, second_random_item = random.sample(group_of_items, 2)
secrets
Mô-đun BTW đã được thêm vào thư viện chuẩn Python trong phiên bản 3.6 python.org/dev/peps/pep-0506
Nếu bạn cũng cần chỉ mục, sử dụng random.randrange
from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
Kể từ Python 3.6, bạn có thể sử dụng secrets
mô-đun, tốt hơn random
mô-đun cho việc sử dụng mật mã hoặc bảo mật.
Để in một phần tử ngẫu nhiên từ danh sách:
import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))
Để in một chỉ mục ngẫu nhiên:
print(secrets.randbelow(len(foo)))
Để biết chi tiết, xem PEP 506 .
Tôi đề xuất một kịch bản để xóa các mục được chọn ngẫu nhiên khỏi danh sách cho đến khi trống:
Duy trì a set
và xóa phần tử nhặt ngẫu nhiên (với choice
) cho đến khi danh sách trống.
s=set(range(1,6))
import random
while len(s)>0:
s.remove(random.choice(list(s)))
print(s)
Ba lần chạy cho ba câu trả lời khác nhau:
>>>
set([1, 3, 4, 5])
set([3, 4, 5])
set([3, 4])
set([4])
set([])
>>>
set([1, 2, 3, 5])
set([2, 3, 5])
set([2, 3])
set([2])
set([])
>>>
set([1, 2, 3, 5])
set([1, 2, 3])
set([1, 2])
set([1])
set([])
random.shuffle
là list
một lần và một trong hai lặp nó hay bật nó tạo ra kết quả. Hoặc là sẽ dẫn đến một luồng "chọn ngẫu nhiên không lặp lại" hoàn toàn đầy đủ, chỉ là sự ngẫu nhiên sẽ được giới thiệu ngay từ đầu.
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1
Trong trăn 2:
random_items = random.sample(population=foo, k=number_of_samples)
Trong trăn 3:
random_items = random.choices(population=foo, k=number_of_samples)
random.choices
với sự thay thế trong khi random.sample
không có sự thay thế.
numpy
giải pháp: numpy.random.choice
Đối với câu hỏi này, nó hoạt động giống như câu trả lời được chấp nhận ( import random; random.choice()
), nhưng tôi đã thêm nó bởi vì lập trình viên có thể đã nhập numpy
(như tôi) và cũng có một số khác biệt giữa hai phương thức có thể liên quan đến trường hợp sử dụng thực tế của bạn.
import numpy as np
np.random.choice(foo) # randomly selects a single item
Đối với khả năng tái tạo, bạn có thể làm:
np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'
Đối với các mẫu của một hoặc nhiều mục , được trả lại dưới dạng array
, vượt qua size
đối số:
np.random.choice(foo, 5) # sample with replacement (default)
np.random.choice(foo, 5, False) # sample without replacement
Làm thế nào để chọn ngẫu nhiên một mục từ danh sách?
Giả sử tôi có danh sách sau:
foo = ['a', 'b', 'c', 'd', 'e']
Cách đơn giản nhất để lấy một mục ngẫu nhiên từ danh sách này là gì?
Nếu bạn muốn gần thực sự ngẫu nhiên , thì tôi đề xuất secrets.choice
từ thư viện chuẩn (Mới trong Python 3.6.):
>>> from secrets import choice # Python 3 only
>>> choice(list('abcde'))
'c'
Ở trên tương đương với khuyến nghị trước đây của tôi, sử dụng một SystemRandom
đối tượng từ random
mô-đun với choice
phương thức - có sẵn trước đó trong Python 2:
>>> import random # Python 2 compatible
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']
Và bây giờ:
>>> sr.choice(foo)
'd'
>>> sr.choice(foo)
'e'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'b'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'c'
>>> sr.choice(foo)
'c'
Nếu bạn muốn lựa chọn giả ngẫu nhiên xác định, hãy sử dụng choice
hàm (đây thực sự là một phương thức ràng buộc trên một Random
đối tượng):
>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>
Điều này có vẻ ngẫu nhiên, nhưng thực tế không phải vậy, mà chúng ta có thể thấy nếu chúng ta lặp lại nó nhiều lần:
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
Đây không phải là về việc Random.choice có thực sự ngẫu nhiên hay không. Nếu bạn sửa hạt giống, bạn sẽ nhận được kết quả có thể lặp lại - và đó là hạt giống được thiết kế cho. Bạn cũng có thể chuyển một hạt giống đến SystemRandom.
sr = random.SystemRandom(42)
Vâng, vâng, bạn có thể truyền cho nó một đối số "hạt giống", nhưng bạn sẽ thấy rằng SystemRandom
đối tượng chỉ đơn giản bỏ qua nó :
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
return None
Nếu bạn cần chỉ mục, chỉ cần sử dụng:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]
Random.choice cũng vậy :)
random.choice(self, seq)
là return seq[int(self.random() * len(seq))]
.
randrange()
mà phương tiện ví dụ như random.SystemRandom().randrange(3<<51)
triển lãm thiên vị đáng kể. Thở dài ...
float
(một nhân đôi của IEEE) chỉ có thể lấy một số lượng giá trị hữu hạn trong [0,1). Random.random()
tạo đầu ra của nó theo cách truyền thống: chọn một số nguyên ngẫu nhiên [0, 2**53)
và chia cho 2**53
(53 là số bit trong một lần). Vì vậy, random()
trả về 2 ** 53 nhân đôi có thể trang bị và bạn có thể chia đều số này thành N đầu ra chỉ khi N là lũy thừa của 2. Độ lệch nhỏ đối với N nhỏ, nhưng xem collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()
. (Random'nextInt () của Java tránh sự thiên vị như vậy.)
2**40
, (đó là 1099511627776), sẽ đủ nhỏ để sự thiên vị không quan trọng trong thực tế? Điều này thực sự cần được chỉ ra trong tài liệu, bởi vì nếu ai đó không tỉ mỉ, họ có thể không mong đợi các vấn đề đến từ phần mã này.
random
sử dụng getrandbits
để có đủ số bit để tạo kết quả cho randrange
s lớn hơn ( random.choice
cũng đang sử dụng số đó). Điều này đúng trên cả 2.7 và 3.5. Nó chỉ sử dụng self.random() * len(seq)
khi getrandbits
không có sẵn. Nó không làm điều ngu ngốc mà bạn nghĩ nó là.
Đây là mã có một biến xác định chỉ số ngẫu nhiên:
import random
foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1)
print (foo[randomindex])
## print (randomindex)
Đây là mã không có biến:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])
Và đây là mã theo cách ngắn nhất và thông minh nhất để làm điều đó:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
(trăn 2.7)
Các mã sau đây chứng minh nếu bạn cần sản xuất các mặt hàng tương tự. Bạn cũng có thể chỉ định số lượng mẫu bạn muốn trích xuất.
Các sample
phương thức trả về một danh sách mới có chứa các yếu tố từ dân, vừa rời khỏi dân gốc không thay đổi. Danh sách kết quả theo thứ tự lựa chọn sao cho tất cả các lát con cũng sẽ là các mẫu ngẫu nhiên hợp lệ.
import random as random
random.seed(0) # don't use seed function, if you want different results in each run
print(random.sample(foo,3)) # 3 is the number of sample you want to retrieve
Output:['d', 'e', 'a']
import random
my_list = [1, 2, 3, 4, 5]
num_selections = 2
new_list = random.sample(my_list, num_selections)
randIndex = random.sample(range(len(my_list)), n_selections)
randIndex.sort()
new_list = [my_list[i] for i in randIndex]
Bản sao của https://stackoverflow.com/a/49682832/4383027
Chúng tôi cũng có thể làm điều này bằng cách sử dụng randint.
from random import randint
l= ['a','b','c']
def get_rand_element(l):
if l:
return l[randint(0,len(l)-1)]
else:
return None
get_rand_element(l)
random.choice()
và random.randrange()
?
None
chỉ cần đóng hộp đến một số điểm ngẫu nhiên sau đó trong đó "phần tử" không hợp lệ kích hoạt một ngoại lệ; hoặc tệ hơn nữa là bạn nhận được một chương trình không chính xác thay vì một ngoại lệ và thậm chí bạn không biết nó.
Bạn chỉ có thể:
from random import randint
foo = ["a", "b", "c", "d", "e"]
print(foo[randint(0,4)])
random.choice(foo)
trả lại liên tiếp hai kết quả khác nhau?