更多'Pythonic'方式替换列表shuffle

时间:2017-03-20 16:28:03

标签: python list

尝试使用偶数项目“洗牌”列表。将列表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]]

5 个答案:

答案 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中,这意味着绝对值的差异可能看起来更小比它真的!):

enter image description here

免责声明:我是该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]