Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用列表理解交换列表中随机元素的范围_Python_Python 2.7_List Comprehension - Fatal编程技术网

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

Python 使用列表理解交换列表中随机元素的范围,python,python-2.7,list-comprehension,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', '

我必须从一个列表中随机选取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']
有没有一种方法可以用列表理解来写这个?这超出了我的理解力


原始列表不会以无序结束,它只是删除了choosen元素。

此功能已内置到random模块中

>>> x = ['a','b','c','d','e','f','g']
>>> shuffle(x)
>>> x
['b', 'a', 'f', 'e', 'c', 'd', 'g']
>>>
如果不想就地修改x,只需使用shufflex[:]


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

正如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]

如果列表很大,则从列表中间一次删除一个随机项可能会很慢,因为每次删除都会压缩剩余的项。最好将未拆下的零件粘在一起。以下函数从给定列表中删除位于假定已排序的给定索引列表中的项,返回提取的项,并作为副作用对列表进行修改:

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']

我将编辑这个问题,问题是我不想洗牌,我想从一个列表中随机选取N个元素,并将它们交换到另一个。@joranbeasley取决于原因,你不这么认为吗?@joranbeasley如果你不知道OP想做什么,那还为时过早,尽管他们可能会澄清。@JohnColeman无论发生什么,OP最终还是会得到一个原始列表中的无序元素列表……那么为什么要重新发明轮子来实现同样的效果呢goal@JoranBeasley你说得对。OP给出的代码产生的净结果与random.shuffle的效果相当,但swap一词的使用向我暗示,他们想用N个换位来做一些事情,这就是我上一条评论背后的内容。我怀疑这里有一些关于random.shuffle的XY问题,答案是Y而不是X,反之亦然。或者-也许这毕竟只是一个愚蠢的家庭作业问题。你必须有一个不太懂python的老师的作业…@JoranBeasley OP的老师一定不太懂python吗?为什么?因为他不能使用已经存在的工具并且已经工作得很好了。。。有一些不错的python初学者任务,但是设置不能使用语言内置的约束是很糟糕的。。。如果他们不想让他们使用这个功能,他们应该用一种不起作用的语言来教他们。我只是不懂下划线,请你解释一下好吗?下划线和其他变量名一样。按照惯例,当你必须捕获某件事情的结果时会用到它,但之后你就不再关心它了。重要的是不要在其他语言中使用这个惯例。例如,我看到有人对导致下划线.js被垃圾收集的答案非常生气。我仍然需要执行类似[z代表z在x中,如果z不在y中]的操作来删除项目,对吗?@Onilol您可以使用代码alist[:n]或alist[0:n]来获取项目0到n,以及alist[n:]或alist[n:-1]来获取项目n到列表末尾。如果你想保持秩序,那么你必须这样做,但是如果秩序不重要,你可以只做x=x[:n]。
>>> x = list("abcdefg")
>>> drawFrom(x,3)
['g', 'e', 'b']
>>> x
['a', 'c', 'd', 'f']