Pau*_*aul 2 python shuffle code-golf
这是一年中的那个时候,程序员想要洗牌,以便没有元素存在于其原始位置(至少在荷兰,我们庆祝Sinterklaas并选择吸管来决定谁写一首诗).有人有一个很好的Python 单一声明吗?
那么,输入示例: range(10)
输出示例: [2,8,4,1,3,7,5,9,6,0]
错误的输出将是[2,8,4,1,3,5,7,9,6,0]因为5它处于原始位置.这意味着5人必须为自己写一首诗,这样就不那么有趣了.
编辑许多人只要需要幸运就重复这项任务,并发现事实上解决方案是令人满意的.这是一种糟糕的方法,因为理论上这可能需要很长时间.巴特确实提出了更好的方法,但由于某种原因,我不能把它变成一个oneliner ......
编辑通过oneliner,我的意思是单一陈述.看起来,Python也能够在一行上压缩多个语句.我不知道.目前有非常好的解决方案,只使用分号来模拟单行上的多线行为.因此:"你能在一个声明中做到吗?"
我发现shuffle可以被滥用来解决这个问题
from random import shuffle
L = ["Anne", "Beth", "Cath", "Dave", "Emma"]
shuffle(L, int=lambda n: int(n - 1))
print L
Run Code Online (Sandbox Code Playgroud)
分布不均匀,但这不是必需的.
#For 100,000 samples
(('Beth', 'Cath', 'Dave', 'Emma', 'Anne'), 13417)
(('Beth', 'Cath', 'Emma', 'Anne', 'Dave'), 6572)
(('Beth', 'Dave', 'Anne', 'Emma', 'Cath'), 3417)
(('Beth', 'Dave', 'Emma', 'Cath', 'Anne'), 6581)
(('Beth', 'Emma', 'Anne', 'Cath', 'Dave'), 3364)
(('Beth', 'Emma', 'Dave', 'Anne', 'Cath'), 6635)
(('Cath', 'Anne', 'Dave', 'Emma', 'Beth'), 1703)
(('Cath', 'Anne', 'Emma', 'Beth', 'Dave'), 1705)
(('Cath', 'Dave', 'Beth', 'Emma', 'Anne'), 6583)
(('Cath', 'Dave', 'Emma', 'Anne', 'Beth'), 3286)
(('Cath', 'Emma', 'Beth', 'Anne', 'Dave'), 3325)
(('Cath', 'Emma', 'Dave', 'Beth', 'Anne'), 3421)
(('Dave', 'Anne', 'Beth', 'Emma', 'Cath'), 1653)
(('Dave', 'Anne', 'Emma', 'Cath', 'Beth'), 1664)
(('Dave', 'Cath', 'Anne', 'Emma', 'Beth'), 3349)
(('Dave', 'Cath', 'Emma', 'Beth', 'Anne'), 6727)
(('Dave', 'Emma', 'Anne', 'Beth', 'Cath'), 3319)
(('Dave', 'Emma', 'Beth', 'Cath', 'Anne'), 3323)
(('Emma', 'Anne', 'Beth', 'Cath', 'Dave'), 1682)
(('Emma', 'Anne', 'Dave', 'Beth', 'Cath'), 1656)
(('Emma', 'Cath', 'Anne', 'Beth', 'Dave'), 3276)
(('Emma', 'Cath', 'Dave', 'Anne', 'Beth'), 6638)
(('Emma', 'Dave', 'Anne', 'Cath', 'Beth'), 3358)
(('Emma', 'Dave', 'Beth', 'Anne', 'Cath'), 3346)
Run Code Online (Sandbox Code Playgroud)
对于均匀分布,可以使用该(更长)版本
from random import shuffle,randint
L=["Anne", "Beth", "Cath", "Dave", "Emma"]
shuffle(L, random=lambda: 1, int=lambda n: randint(0, n - 2))
print L
# For 100,000 samples
(('Beth', 'Cath', 'Dave', 'Emma', 'Anne'), 4157)
(('Beth', 'Cath', 'Emma', 'Anne', 'Dave'), 4155)
(('Beth', 'Dave', 'Anne', 'Emma', 'Cath'), 4099)
(('Beth', 'Dave', 'Emma', 'Cath', 'Anne'), 4141)
(('Beth', 'Emma', 'Anne', 'Cath', 'Dave'), 4243)
(('Beth', 'Emma', 'Dave', 'Anne', 'Cath'), 4208)
(('Cath', 'Anne', 'Dave', 'Emma', 'Beth'), 4219)
(('Cath', 'Anne', 'Emma', 'Beth', 'Dave'), 4087)
(('Cath', 'Dave', 'Beth', 'Emma', 'Anne'), 4117)
(('Cath', 'Dave', 'Emma', 'Anne', 'Beth'), 4127)
(('Cath', 'Emma', 'Beth', 'Anne', 'Dave'), 4198)
(('Cath', 'Emma', 'Dave', 'Beth', 'Anne'), 4210)
(('Dave', 'Anne', 'Beth', 'Emma', 'Cath'), 4179)
(('Dave', 'Anne', 'Emma', 'Cath', 'Beth'), 4119)
(('Dave', 'Cath', 'Anne', 'Emma', 'Beth'), 4143)
(('Dave', 'Cath', 'Emma', 'Beth', 'Anne'), 4203)
(('Dave', 'Emma', 'Anne', 'Beth', 'Cath'), 4252)
(('Dave', 'Emma', 'Beth', 'Cath', 'Anne'), 4159)
(('Emma', 'Anne', 'Beth', 'Cath', 'Dave'), 4193)
(('Emma', 'Anne', 'Dave', 'Beth', 'Cath'), 4177)
(('Emma', 'Cath', 'Anne', 'Beth', 'Dave'), 4087)
(('Emma', 'Cath', 'Dave', 'Anne', 'Beth'), 4150)
(('Emma', 'Dave', 'Anne', 'Cath', 'Beth'), 4268)
(('Emma', 'Dave', 'Beth', 'Anne', 'Cath'), 4109)
Run Code Online (Sandbox Code Playgroud)
这个怎么运作
这是代码 random.shuffle()
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.
"""
if random is None:
random = self.random
for i in reversed(xrange(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = int(random() * (i+1))
x[i], x[j] = x[j], x[i]
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都是通过定位线来实 j = int(random() * (i+1))
第一个(非均匀)有效地使线条像这样工作
j = int(random() * (i + 1) - 1)
Run Code Online (Sandbox Code Playgroud)
因此,我们获得(0..i-1)而不是(1..i)的范围
第二个解决方案替换random()为始终返回1的函数,randint而不是使用int.所以这条线现在就像这样
j = randint(0, i - 1)
Run Code Online (Sandbox Code Playgroud)
在对数字列表进行洗牌之后,让这个[i]人为列表中的第一个人写一首诗(然后买礼物!)[i+1]:这样,就永远不会有人吸引他或她自己.当然,最后一个应该指向第一个......