Pop l:从列表中弹出随机元素的最Pytn的方法是什么

说我有一个列表x与未知长度,我想随机弹出一个元素,以便列表不包含元素之后。

我可以使用poprandom.randintlen的相当不方便的组合,并希望看到更短或更好的解决方案:

import random
x = [1,2,3,4,5,6]
x.pop(random.randint(0,len(x)-1))

我试图实现的是从列表中连续弹出随机元素(即随机弹出一个元素并将其移动到字典,随机弹出另一个元素并将其移动到另一个字典,...)

请注意,我使用 Pytn 2.6,并没有通过搜索功能找到任何解决方案。

121

你不应该从列表的中间删除东西,因为列表在我所知道的所有 Pytn 实现中都被实现为数组,所以这是一个O(n)操作。

如果您确实需要此功能作为算法的一部分,则应该检查像blist这样的数据结构,该数据结构支持从中间进行有效删除。

在纯 Pytn 中,如果你不需要访问剩余的元素,你可以做的只是先洗牌列表,然后遍历它:

lst = [1,2,3]
random.shuffle(lst)
for x in lst:
  # ...

如果你真的需要剩余的(这是一个有点 code 气味,恕我直言),至少你可以pop()从列表的末尾现在(这是快!):

while lst:
  x = lst.pop()
  # do something with the element      

通常,如果您使用功能更强大的风格,而不是改变状态(就像您使用列表一样),您通常可以更优雅地表达您的程序。

65

你不会得到比这更好的,但这里有一个轻微的改进:

x.pop(random.randrange(len(x)))

有关random.randrange()的文档:

randrange ([start],stop [,step])
返回从range(start, stop, step)中随机选择的元素。这等效于cice(range(start, stop, step)),但实际上并不构建范围对象。

19

要从列表中删除随机索引处的单个元素,如果列表元素的其余部分的顺序无关紧要:

import random
L = [1,2,3,4,5,6]
i = random.randrange(len(L)) # get random index
L[i], L[-1] = L[-1], L[i]    # swap with the last element
x = L.pop()                  # pop last element O(1)

交换用于避免从列表中间删除时的 O(n)行为。

12

尽管许多答案建议使用random.shuffle(x)x.pop(),但它在大数据上的速度非常慢。启用 shuffle 时,10000元素列表所需的时间约为6 seconds。当禁用 shuffle 时,速度为0.2s

在测试了上面所有给定的方法之后,最快的方法被证明是由 @ jfs 编写的

import random
L = [1,"2",[3],(4),{5:"6"},'etc'] #you can take mixed or pure list
i = random.randrange(len(L)) # get random index
L[i], L[-1] = L[-1], L[i]    # swap with the last element
x = L.pop()                  # pop last element O(1)

in support of my claim here is the time complexity chart from this source enter image description here

如果列表中没有重复项,

你也可以使用集合来实现你的目的。一旦列表变成集合重复将被删除。remove by valueremove random成本O(1),即非常有效。这是我能想出的最干净的方法。

L=set([1,2,3,4,5,6...]) #directly input the list to inbuilt function set()
while 1:
    r=L.pop()
    #do something with r , r is random element of initial list L.

lists支持A+B选项不同,sets还支持A-B (A minus B)以及A+B (A union B)A.intersection(B,C,D)

可选的

如果你想要在列表的头部和尾部执行操作时的速度,请使用 pytn dequeue(双端队列)来支持我的说法这里是图像。

enter image description here

本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处

(861)
Python简单数值运算:OpenCV-Python中的简单数字识别OCR
上一篇
Python创建一个文件:试图在Python中创建一个KML文件
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(54条)