2013-07-15 34 views
45

Tại sao là random.shuffle trả về None trong python?Tại sao random.shuffle trả về None?

>>> 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?

+0

không phải là giá trị ngẫu nhiên mà là ngẫu nhiên xáo trộn danh sách. – alvas

+2

Liên quan: Các hàm [sắp xếp() và ngược() không hoạt động] (http://stackoverflow.com/q/16460616) –

Trả lời

71

random.shuffle() thay đổi x danh sách tại chỗ.

Phương pháp API Python thay đổi cấu trúc tại chỗ thường trả lại None, không phải cấu trúc dữ liệu đã sửa đổi.

Nếu bạn muốn tạo ra một mới danh sách ngẫu nhiên xáo trộn dựa trên hiện có, nơi mà danh sách hiện có được giữ theo thứ tự, bạn có thể sử dụng random.sample() với toàn bộ chiều dài 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 chìa khóa sắp xếp:

shuffled = sorted(x, key=lambda k: random.random()) 

nhưng điều này gọi sắp xếp (một O (NlogN) hoạt động), trong khi lấy mẫu đến Inpu t chiều dài chỉ mất O (N) hoạt động (quá trình tương tự như random.shuffle() được sử dụng, trao đổi các giá trị ngẫu nhiên từ một hồ bơi thu hẹp).

Demo:

>>> 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'] 
+0

Còn về '.pop()' thì sao? Điều đó sẽ loại bỏ chỉ mục đã cho khỏi danh sách và trả về mục đó hoặc tôi thiếu một cái gì đó – TerryA

+0

@ Haidro: chắc chắn, '.pop()' được ghi lại rõ ràng là trả về phần tử đã xóa. Điều chỉnh từ ngữ. –

+2

Có sử dụng chức năng 'khóa' có giá trị ngẫu nhiên thực sự được đảm bảo không? Một số thuật toán sắp xếp nhanh sẽ giảm nếu so sánh không tự nhất quán. Tôi có thể thấy điều này làm việc một trong hai cách, tùy thuộc vào thực hiện (trang trí-sắp xếp-undecorate sẽ chỉ cần áp dụng 'chìa khóa' một lần trên mỗi yếu tố như vậy sẽ được xác định rõ). – torek

6

Theo docs:

Xáo chuỗi x tại chỗ. Đối số ngẫu nhiên tùy chọn là hàm 01 đối sốtrả về một float ngẫu nhiên trong [0.0, 1.0); bởi mặc định, đây là hàm ngẫu nhiên().

>>> x = ['foo','bar','black','sheep'] 
>>> from random import shuffle 
>>> shuffle(x) 
>>> x 
['bar', 'black', 'sheep', 'foo'] 
4

shuffle đổi các danh sách tại chỗ. Điều này là tốt đẹp, bởi vì sao chép một danh sách lớn sẽ là nguyên trên không nếu bạn không cần danh sách gốc nữa.

Theo "rõ ràng là tốt hơn so với tiềm ẩn" nguyên tắc pythonic style, trở về danh sách sẽ là một ý tưởng tồi, bởi vì khi đó người ta có thể nghĩ rằng nó một cái mới mặc dù trên thực tế nó không phải là.

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ì đó giống như

new_x = list(x) # make a copy 
random.shuffle(new_x) 

đó là độc đáo rõ ràng. Nếu bạn cần thành ngữ này thường xuyên, hãy quấn nó thành một hàm shuffled (xem sorted) trả về new_x.

23

Tôi nghĩ phương pháp này cũng hoạt động.

import random 
shuffled = random.sample(original, len(original)) 
1

Tôi có khoảnh khắc aha của tô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'] 
+0

Vì python thực hiện "copy-by-values" theo mặc định thay vì pass-by-reference =) http://stackoverflow.com/a/986495/610569 – alvas

1
shuffle(x) 

không trả lại bất kỳ giá trị. Thay vào đó, hàm đó trộn chính biến đó.

Vì vậy, không nên cố gắng

print shuffle(x) 

thay vì chỉ in các biến như thế này.

>>> x = ['foo','bar','black','sheep'] 
>>> from random import shuffle 
>>> x 
['bar', 'black', 'foo', 'sheep'] 
Các vấn đề liên quan