Câu hỏi 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 để truy xuất một mục ngẫu nhiên từ danh sách này là gì?


1304
2017-11-20 18:42


gốc




Các 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 bảo mật mã hóa (ví dụ: để tạo cụm mật khẩu từ danh sách từ), hãy sử dụng random.SystemRandom lớp học:

import random

foo = ['battery', 'correct', 'horse', 'staple']
secure_random = random.SystemRandom()
print(secure_random.choice(foo))

2134
2017-11-20 18:46



Vui lòng cải thiện câu trả lời của bạn, bởi vì bạn đề xuất phương pháp không an toàn! Python 2 random không thể được sử dụng cho các ứng dụng thực tế, yêu cầu ngẫu nhiên tốt, và điều này được nêu trong tài liệu chính thức. Bạn phải sử dụng một trong hai os.urandom và ánh xạ nó vào chỉ mục trong danh sách hoặc sử dụng secrets.choice chức năng trong Python 3.6 - Vladimir Ignatyev
Có ổn không khi cải thiện 10 tuổi trả lời? Tôi đoán mọi người nên chú ý đến điều đó. - Claud H
@ClaudH CÓ! SO hành vi cũng như một loại bách khoa toàn thư / kiến ​​thức cơ sở - cải tiến chào đón! Các trường hợp khác, khi câu trả lời hết hạn cũng quan trọng để cải thiện, ngay cả khi câu trả lời là cũ. - drevicko
@ drevicko Những gì tôi có nghĩa là người trả lời không nên quan tâm nhiều nếu câu trả lời của mình bị lỗi thời (đặc biệt là nếu 10 năm trôi qua). Do đó, tôi không chấp nhận ý kiến ​​'vui lòng cải thiện câu trả lời của bạn'. - Claud H


Trong trường hợp bạn cũng cần chỉ mục:

foo = ['a', 'b', 'c', 'd', 'e']
from random import randrange
random_index = randrange(0,len(foo))
print foo[random_index]

125
2017-09-11 15:31



Tôi nghĩ ý anh ấy là, có một choice trong thư viện Python vì một lý do. Tôi chắc rằng Guido và cộng đồng không chỉ chọn cách tiếp cận đầu tiên đến với tâm trí của họ, nhưng sử dụng một phương pháp tối ưu cho một trường hợp sử dụng chung. Tất nhiên có thể có một số vấn đề đặc biệt yêu cầu thực hiện tùy chỉnh (ví dụ: trong các hệ thống thời gian thực, trong môi trường bộ nhớ thấp, v.v.), nhưng thường không phải như vậy. - Richard Otvos
Tôi thích random.choice(list(enumerate(foo))) cho điều này .. - wim
@wim Đó là O(n) trong khi phương pháp hoàn hảo của Juampi là O(1). - Veedrac
Như với range(..), bạn không cần phải cung cấp đối số đầu tiên trong randrange(..) nếu đó là số không. Đó là: randrange(len(foo)) không giống như trong câu trả lời. - Evgeni Sergeev


Nếu bạn muốn chọn ngẫu nhiên nhiều mục từ 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ỉ đang kéo một mục duy nhất từ ​​một danh sách, thì sự lựa chọn ít phức tạp hơn, khi 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, mặc dù 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). Tuy nhiên random.choice(tuple(some_set)) có thể là một tùy chọn để nhận một mục từ một bộ.


108
2018-05-27 17:07





Tôi đề xuất một tập lệnh để xóa các mục đã nhặt ngẫu nhiên khỏi danh sách cho đến khi nó trống:

Duy trì một set và loại bỏ yếu 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 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([])

27
2018-05-13 02:47



Hoặc bạn có thể random.shuffle các list một lần và lặp lại nó hoặc bật nó để tạo ra kết quả. Hoặc sẽ dẫn đến một dòng "chọn ngẫu nhiên không lặp lại" hoàn toàn thích hợp, nó chỉ là sự ngẫu nhiên sẽ được giới thiệu ngay từ đầu. - ShadowRanger
Về mặt lý thuyết bạn có thể sử dụng pop () phương thức của một tập hợp để loại bỏ một phần tử tùy ý khỏi một tập hợp và trả về nó, nhưng nó có thể không đủ ngẫu nhiên. - Joubarc


Theo Python 3.6 bạn có thể sử dụng secrets mô-đun, thích hợp hơn với random mô-đun để 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 chỉ mục ngẫu nhiên:

print(secrets.randbelow(len(foo)))

Để biết chi tiết, hãy xem PEP 506.


27
2017-12-05 16:52





Đây là mã có một biến xác định chỉ mục 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 để thực hiện:

import random

foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))

(python 2.7)


7
2018-05-25 14:57





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 python 3:

random_items = random.choices(population=foo, k=number_of_samples)

7
2017-11-29 16:40



Lưu ý rằng random.choices là với sự thay thế trong khi random.sample không cần thay thế. - CentAu