เหตุใดจึงrandom.shuffle
กลับมาNone
ใน Python
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
ฉันจะรับค่าสับแทนได้None
อย่างไร
เหตุใดจึงrandom.shuffle
กลับมาNone
ใน Python
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
ฉันจะรับค่าสับแทนได้None
อย่างไร
คำตอบ:
random.shuffle()
การเปลี่ยนแปลงx
รายการในสถานที่
เมธอด Python API ที่เปลี่ยนโครงสร้างแบบแทนที่โดยทั่วไปจะส่งคืนNone
ไม่ใช่โครงสร้างข้อมูลที่แก้ไข
หากคุณต้องการสร้างรายการที่สุ่มสับใหม่โดยอิงจากรายการที่มีอยู่ซึ่งรายการที่มีอยู่จะถูกเก็บไว้ตามลำดับคุณสามารถใช้random.sample()
กับอินพุตแบบเต็มความยาว:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
คุณยังสามารถใช้sorted()
กับrandom.random()
คีย์การเรียงลำดับ:
shuffled = sorted(x, key=lambda k: random.random())
แต่สิ่งนี้เรียกใช้การเรียงลำดับ (การดำเนินการ O (NlogN)) ในขณะที่การสุ่มตัวอย่างตามความยาวอินพุตจะใช้การดำเนินการ O (N) เท่านั้น (กระบวนการเดียวกับที่random.shuffle()
ใช้โดยสลับค่าสุ่มจากพูลที่ลดขนาด)
การสาธิต:
>>> 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
ฟังก์ชันสุ่มมูลค่ารับประกันจริงหรือไม่? อัลกอริทึมการเรียงลำดับที่รวดเร็วบางอย่างจะล้มเหลวหากการเปรียบเทียบไม่สอดคล้องกันในตัวเอง ฉันสามารถเห็นการทำงานนี้ได้ทั้งสองวิธีขึ้นอยู่กับการนำไปใช้งาน (การตกแต่ง - จัดเรียง - ไม่ได้รับการตกแต่งจะต้องใช้key
เพียงครั้งเดียวในแต่ละองค์ประกอบจึงจะได้รับการกำหนดไว้อย่างชัดเจน)
key
callable ใช่มันรับประกันได้เนื่องจากแต่ละค่าจะได้รับคีย์สุ่มหนึ่งครั้ง
วิธีนี้ได้ผลเช่นกัน
import random
shuffled = random.sample(original, len(original))
ตามเอกสาร :
สลับลำดับ x ในตำแหน่ง อาร์กิวเมนต์ที่เป็นทางเลือกแบบสุ่มคือฟังก์ชัน 0 อาร์กิวเมนต์ที่ส่งคืนค่าลอยแบบสุ่มใน [0.0, 1.0); ตามค่าเริ่มต้นนี่คือฟังก์ชันสุ่ม ()
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffle
แก้ไขรายการในสถานที่ นี่เป็นสิ่งที่ดีเพราะการคัดลอกรายการจำนวนมากจะเป็นค่าใช้จ่ายที่บริสุทธิ์หากคุณไม่ต้องการรายการต้นฉบับอีกต่อไป
ตามหลักการ"Explicit is better than implicit"ของpythonic style การกลับรายการจะเป็นความคิดที่ไม่ดีเพราะอาจมีคนคิดว่าเป็นรายการใหม่แม้ว่าในความเป็นจริงจะไม่ใช่ก็ตาม
หากคุณไม่จำเป็นต้องมีรายการสดคุณจะต้องเขียนสิ่งที่ต้องการ
new_x = list(x) # make a copy
random.shuffle(new_x)
ซึ่งมีความชัดเจนอย่างยิ่ง หากคุณต้องการสำนวนนี้บ่อยห่อมันในการทำงานshuffled
(ดูsorted
) new_x
ผลตอบแทนที่
ฉันมีช่วงเวลาที่ดีกับแนวคิดเช่นนี้:
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']
Python API ซึ่งเปลี่ยนโครงสร้างแทนตัวเองจะคืนค่าNoneเป็นเอาต์พุต
list = [1,2,3,4,5,6,7,8]
print(list)
เอาต์พุต: [1, 2, 3, 4, 5, 6, 7, 8]
from random import shuffle
print(shuffle(list))
เอาต์พุต: ไม่มี
from random import sample
print(sample(list, len(list)))
เอาต์พุต: [7, 3, 2, 4, 5, 6, 1, 8]
คุณสามารถส่งคืนรายการแบบสุ่มโดยใช้random.sample()
ตามคำอธิบายของผู้อื่น มันทำงานโดยการสุ่มตัวอย่างองค์ประกอบ k จากรายการโดยไม่ต้องเปลี่ยน ดังนั้นหากมีองค์ประกอบที่ซ้ำกันในรายการของคุณองค์ประกอบเหล่านั้นจะได้รับการปฏิบัติโดยไม่ซ้ำกัน
>>> 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]