这是来自教育课程的一段非常简单的代码。
import random
l=[1,2,3,4,5,6,7,8,9,10]
sorted(l, key=lambda x:random.random())
因此,我们以随机顺序对列表进行了洗牌。例如:
[7, 4, 9, 1, 10, 8, 6, 3, 2, 5]
我打印了此列表的生成随机值。他们是:
0.2991455199706915
0.6909636166874692
0.6588993793087247
0.2464197124358396
0.8021604268319649
0.4982523946322083
0.14000601629016884
0.3598504556263765
0.25865161068212017
0.3534562884598361
我的问题是这些值之一如何与列表中的索引连接?例如,为什么 x = 0.2991455199706915 的值表示列表的第 7 个元素,而 x = 0.6909636166874692 的值表示列表的第 4 个元素?
例如,如果是在 C++ 中完成的,我会将随机函数生成的值从区间 [0,1) 缩放到区间 [0,10),并且显然将生成的值四舍五入到最接近的整数。看来我在幕后也有类似的过程。我想知道它是如何工作的。
如果您更改此设置,以便将生成的排序顺序键保存在字典中并查看它,您会发现它完全按照应有的方式进行:
import random
keys = {}
def get_key(x):
print("Getting a key for", x)
keys[x] = key = random.random()
return key
print(sorted([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], key=get_key))
print(keys)
print(sorted((sort_key, original_number) for (original_number, sort_key) in keys.items()))
这会打印出来(例如——它是随机的!,我冒昧地缩短了数字)
Getting a key for 1
Getting a key for 2
[...]
Getting a key for 10
[4, 2, 5, 10, 8, 6, 1, 9, 3, 7]
{1: 0.91042, 2: 0.12800, 3: 0.97425, 4: 0.04509, 5: 0.27770, 6: 0.73670, 7: 0.98525, 8: 0.42114, 9: 0.95332, 10: 0.41352}
[(0.04509, 4), (0.12800, 2), (0.27770, 5), (0.41352, 10), (0.42114, 8), (0.73670, 6), (0.91042, 1), (0.95332, 9), (0.97425, 3), (0.98525, 7)]
如您所见,当
keys
字典按值排序时,您会得到相同的 4,2,5,10,... 顺序。
但是,这是一种不好的随机播放列表的方法 - 人们应该简单地使用
random.shuffle()
(在列表的副本上,如果你不想弄乱原始内容),它实现了 Fisher-Yates shuffle。