尝试使用偶数项目“洗牌”列表。将列表L
拆分为一半并交替从每个列表中取一个元素。
我已经尝试了pop
,但这种做法无法让我进入单行班。 (while
循环)我知道可能有一些更简洁的方法可以通过它。
来自shuffle
的{{1}}也不是我所需要的 - 因为它会使整个订单随机化,而不是在拆分列表之间交替。
如果无法使用单行,那是因为它在random
循环中更具可读性吗?
while
其他尝试:
def shuffle(L):
'''
I apologize in advance for how wet the following code is...
Example:
>>> shuffle([1, 2, 3, 4, 5, 6])
[1, 4, 2, 5, 3, 6]
'''
return [L[:(len(L)//2)][0], L[(len(L)//2):][0], L[:(len(L)//2)][1], L[(len(L)//2):][1], L[:(len(L)//2)][2], L[(len(L)//2):][2]]
答案 0 :(得分:4)
将切片分配与步骤一起使用:
def shuffle(l):
result = [None] * len(l)
# Put the first half of l in the even indices of result
result[::2] = l[:len(l)//2]
# Put the second half of l in the odd indices of result
result[1::2] = l[len(l)//2:]
return result
答案 1 :(得分:3)
如果我理解正确,您也可以在压缩后选择itertools.chain.from_iterable
以获得交替效果。
from itertools import chain
def shuff(l):
return list(chain.from_iterable(zip(l[:len(l)//2], l[len(l)//2:])))
<强>演示强>
>>> shuff(list(range(1, 7))
[1, 4, 2, 5, 3, 6]
答案 2 :(得分:2)
一种可能性(需要外部库,但配方也可以在itertools
-recipes section中找到)是:
from iteration_utilities import roundrobin
def shuffle(L):
return list(roundrobin(L[:len(L)//2], L[len(L)//2:]))
这可能比列表赋值慢,但它也适用于任意数量的迭代,没有问题,并且不需要奇数大小的输入处理:
>>> shuffle([1, 2, 3, 4, 5, 6, 7])
[1, 4, 2, 5, 3, 6, 7]
>>> shuffle([1, 2, 3, 4, 5, 6])
[1, 4, 2, 5, 3, 6]
我做了一些timings和@ user2357112 definetly有最快的解决方案,但我的解决方案至少在第二位(请注意,此图表在log-log中,这意味着绝对值的差异可能看起来更小比它真的!):
免责声明:我是该iteration_utilities
库的作者。
答案 3 :(得分:1)
使用模数和底线除法进行指数计算的列表理解
[ L[(i + (i % 2)*len(L))//2] for i in range(len(L)) ] # for case of even len(L)
一般情况下还有一行
[ L[i//2 + (i % 2)*len(L)//2] for i in range(2*(len(L)//2)) ] + [L[-1]]*(len(L) % 2)
索引calc (i + (i % 2)*len(L))//2
可以解析为添加
i//2
,其中包含0, 0, 1, 1, 2, 2 ...
和
(i % 2)*len(L)//2
其中(i % 2)
替代0,1为偶数/奇数i
0, len(L)//2, 0, len(L)//2, 0, len(L)//2 ...
和
0, len(L)//2, 1, 1 + len(L)//2, 2, 2 + len(L)//2 ...
答案 4 :(得分:0)
找到两个解决方案。第一个非常unpythonic(使用python 2.7)
a = [1, 2, 3, 4, 5, 6] # intial array
方法一(使用字符串魔法):
[int(p) for p in ' '.join([str(x) + ' ' + str(y) for x, y in zip(a[:len(a) / 2], a[len(a) / 2:])]).split(' ')]
方法二:
[i for Tuple in zip(a[:len(a) / 2], a[len(a) / 2:]) for i in Tuple]