Tại sao random.shuffle
quay lại None
bằng Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Làm cách nào để nhận giá trị xáo trộn thay vì None
?
Tại sao random.shuffle
quay lại None
bằng Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Làm cách nào để nhận giá trị xáo trộn thay vì None
?
Câu trả lời:
random.shuffle()
thay đổi x
danh sách tại chỗ .
Các phương thức API Python thay đổi cấu trúc tại chỗ thường trả về None
, không phải cấu trúc dữ liệu đã sửa đổi.
Nếu bạn muốn tạo một danh sách mới được xáo trộn ngẫu nhiên dựa trên danh sách hiện có, trong đó danh sách hiện có được giữ theo thứ tự, bạn có thể sử dụng random.sample()
với độ dài đầy đủ của đầu vào:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
Bạn cũng có thể sử dụng sorted()
với random.random()
cho một khóa sắp xếp:
shuffled = sorted(x, key=lambda k: random.random())
nhưng điều này yêu cầu sắp xếp (một hoạt động O (NlogN)), trong khi lấy mẫu theo độ dài đầu vào chỉ thực hiện các hoạt động O (N) (quy trình tương tự như random.shuffle()
được sử dụng, hoán đổi các giá trị ngẫu nhiên từ một nhóm thu hẹp).
Bản giới thiệu:
>>> import random
>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.sample(x, len(x))
['bar', 'sheep', 'black', 'foo']
>>> sorted(x, key=lambda k: random.random())
['sheep', 'foo', 'black', 'bar']
>>> x
['foo', 'bar', 'black', 'sheep']
key
hàm có giá trị ngẫu nhiên có thực sự đảm bảo không? Một số thuật toán sắp xếp nhanh bị bỏ qua nếu các phép so sánh không tự nhất quán. Tôi có thể thấy điều này hoạt động theo cả hai cách, tùy thuộc vào việc triển khai (trang trí-sắp xếp-trang trí sẽ chỉ cần áp dụng key
một lần trên mỗi phần tử vì vậy sẽ được xác định rõ).
key
tệp có thể gọi. Vì vậy, có, nó được đảm bảo vì mỗi giá trị được cung cấp khóa ngẫu nhiên của chúng chính xác một lần.
Theo tài liệu :
Xáo trộn chuỗi x tại chỗ. Đối số tùy chọn ngẫu nhiên là một hàm 0 đối số trả về một số thực ngẫu nhiên trong [0.0, 1.0); theo mặc định, đây là hàm random ().
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffle
sửa đổi danh sách tại chỗ. Điều này là tốt, bởi vì sao chép một danh sách lớn sẽ là chi phí thuần túy nếu bạn không cần danh sách gốc nữa.
Theo nguyên tắc "rõ ràng tốt hơn là ngầm hiểu" của phong cách pythonic , trả lại danh sách sẽ là một ý tưởng tồi, bởi vì khi đó người ta có thể nghĩ rằng đó là một danh sách mới mặc dù thực tế không phải vậy.
Nếu bạn làm cần một danh sách trong lành, bạn sẽ phải viết một cái gì đó như
new_x = list(x) # make a copy
random.shuffle(new_x)
đó là rõ ràng độc đáo. Nếu bạn cần thành ngữ này thường xuyên, hãy gói nó trong một hàm shuffled
(xem sorted
) trả về new_x
.
Tôi đã có một khoảnh khắc tuyệt vời với khái niệm này như thế này:
from random import shuffle
x = ['foo','black','sheep'] #original list
y = list(x) # an independent copy of the original
for i in range(5):
print shuffle(y) # shuffles the original "in place" prints "None" return
print x,y #prints original, and shuffled independent copy
>>>
None
['foo', 'black', 'sheep'] ['foo', 'black', 'sheep']
None
['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
None
['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
None
['foo', 'black', 'sheep'] ['black', 'foo', 'sheep']
None
['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
Các API Python tự thay đổi cấu trúc tại chỗ trả về Không có ở dạng đầu ra.
list = [1,2,3,4,5,6,7,8]
print(list)
Đầu ra: [1, 2, 3, 4, 5, 6, 7, 8]
from random import shuffle
print(shuffle(list))
Đầu ra: Không có
from random import sample
print(sample(list, len(list)))
Đầu ra: [7, 3, 2, 4, 5, 6, 1, 8]
Bạn có thể trả lại danh sách xáo trộn bằng cách sử dụng random.sample()
như những người khác giải thích. Nó hoạt động bằng cách lấy mẫu k phần tử từ danh sách mà không cần thay thế . Vì vậy, nếu có các phần tử trùng lặp trong danh sách của bạn, chúng sẽ được xử lý duy nhất.
>>> l = [1,4,5,3,5]
>>> random.sample(l,len(l))
[4, 5, 5, 3, 1]
>>> random.sample(l,len(l)-1)
[4, 1, 5, 3]
>>> random.sample(l,len(l)-1)
[3, 5, 5, 1]