使用列表理解交换列表中随机元素的范围

时间:2016-10-21 16:25:56

标签: python python-2.7 list-comprehension

我必须随机从列表中选择N个元素,从列表中删除它们并将它们添加到另一个元素中。到目前为止,我的方法是这样的:

import random

x = ['a','b','c','d','e','f','g']
y = []
for v in reversed(list(x)):
  z = x.pop(x.index(random.choice(x)))
  y.append(z)

输出:

['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'f', 'g']
['a', 'b', 'c', 'd', 'g']
['b', 'c', 'd', 'g']
['b', 'c', 'g']
['c', 'g']
['g']
['e', 'f', 'a', 'd', 'b', 'c', 'g']

有没有办法用列表推导来写这个?这超出了我的理解范围。

原始列表没有结束洗牌,只是删除了选择的元素。

4 个答案:

答案 0 :(得分:5)

此功能已内置于随机模块

>>> x = ['a','b','c','d','e','f','g']
>>> shuffle(x)
>>> x
['b', 'a', 'f', 'e', 'c', 'd', 'g']
>>>

如果您不想修改x,请使用shuffle(x[:])

答案 1 :(得分:3)

y = [x.pop(random.randrange(len(x))) for _ in range(len(x))]

如果你真的想这样做,是的。有更好的方法。

答案 2 :(得分:0)

正如danidee指出的那样,您可以使用随机模块的shuffle函数来执行此操作:

import random
x = [1, 2, 3, 4, 5, 6]
random.shuffle(x)
print(x)

但是,如果您只需要列表中的n项,请使用以下代码:

import random
x = [1, 2, 3, 4, 5, 6]
n = 4
y = random.shuffle(x)[0:n]
print(x)
print(y)

这可能会打印出来:

[6, 3, 2, 1, 4, 5]
[6, 3, 2, 1]

答案 3 :(得分:0)

从列表中间一次删除一个随机项可能很慢(如果列表完全没有),因为每次删除都会压缩剩余的项。将未移除的部件组合在一起可能更好。以下函数从给定列表中删除位于给定索引列表(假定为已排序)的项目,返回提取的项目,并将列表变为副作用:

def extract(myList,indices):
    items = myList[:]
    myList.clear()
    extracted = []
    i = 0
    for j in indices:
        myList.extend(items[i:j])
        extracted.append(items[j])
        i = j + 1
    myList.extend(items[i:]) #last fragment, if any
    return extracted

使用此功能,您可以编写一个函数,从列表中随机返回n个项目,并改变原始列表,保持其余项目的顺序正确:

import random

def drawFrom(myList,n):
    chosen = sorted(random.sample(range(len(myList)),n))
    extracted = extract(myList,chosen)
    random.shuffle(extracted)
    return extracted

例如:

>>> x = list("abcdefg")
>>> drawFrom(x,3)
['g', 'e', 'b']
>>> x
['a', 'c', 'd', 'f']