在Python 3.4中随机化两个列表并维护顺序

时间:2014-04-30 00:21:20

标签: python-3.x

我基本上问的问题与问here完全相同,但是对于Python 3.4.0。

在3.4.0中,此代码:

a = ["Spears", "Adele", "NDubz", "Nicole", "Cristina"]
b = [1, 2, 3, 4, 5]

combined = zip(a, b)
random.shuffle(combined)

a[:], b[:] = zip(*combined)

不起作用。在3.4.0中执行此操作的正确方法是什么?

4 个答案:

答案 0 :(得分:5)

在python 3中,zip返回一个zip对象(即它来自python 2的itertools.izip)。

您需要强制它实现列表:

combined = list(zip(a, b))

答案 1 :(得分:2)

如果内存紧张,您可以编写自己的随机播放功能,以避免创建压缩列表。 Python中的那个并不是很复杂

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.

    Do not supply the 'int' argument.
    """

    randbelow = self._randbelow
    for i in reversed(range(1, len(args[0]))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = randbelow(i+1) if random is None else int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

你的功能可能就是这样:

def shuffle2(a, b):
    for i in reversed(range(1, len(a))):
        j = int(random.random() * (i+1))
        a[i], a[j] = a[j], a[i]
        b[i], b[j] = b[j], b[i]

一致地随机播放任意数量的列表

def shuffle_many(*args):
    for i in reversed(range(1, len(args[0]))):
        j = int(random.random() * (i+1))
        for x in args: 
            x[i], x[j] = x[j], x[i]

例如

>>> import random
>>> def shuffle_many(*args):
...     for i in reversed(range(1, len(args[0]))):
...         j = int(random.random() * (i+1))
...         for x in args: 
...             x[i], x[j] = x[j], x[i]
... 
>>> a = ["Spears", "Adele", "NDubz", "Nicole", "Cristina"]
>>> b = [1, 2, 3, 4, 5]
>>> shuffle_many(a, b)
>>> a
['Adele', 'Spears', 'Nicole', 'NDubz', 'Cristina']
>>> b
[2, 1, 4, 3, 5]

答案 2 :(得分:0)

combined = zip(a,b)更改为combined = list(zip(a,b))。你需要一个列表,而不是一个迭代器,以便进行随机播放。

答案 3 :(得分:0)

在Python 3中,zip返回一个迭代器而不是一个列表,所以在将它混洗之前将其强制转换为一个列表:

combined = list(zip(a, b))