在Python

时间:2017-12-01 05:14:56

标签: python

我有一个列表[1,2,3,3],我想多次从这个列表中选择一个随机元素。但是,我不希望我的随机生成器多次从同一索引中选择相同的元素。

我现在所拥有的:

[1,2,3,3] --> [2] with index 1
[1,2,3,3] --> [1] with index 0       
[1,2,3,3] --> [2] with index 1       (this is wrong because chose the same index)

我想要的是:

[1,2,3,3] --> [2] with index 1
[1,2,3,3] --> [1] with index 0       
[1,2,3,3] --> [3] with index 3       
[1,2,3,3] --> [3] with index 4       (this is perfect, no repeats!)

我该怎么做才能解决这个问题?函数random.choice(...)本身并没有解决这个问题。

更新:我注意到你们中的一些人建议我使用shuffle。这是一个非常好的主意。但是,如果我想在以后跟踪原始索引怎么办?我不认为随机播放可以做到这一点,对吗?

4 个答案:

答案 0 :(得分:2)

以下生成器以随机顺序生成(index, element)对,同时保持原始列表不变:

def gen(lst):
    lst2 = list(enumerate(lst))
    random.shuffle(lst2)
    for x in lst2:
        yield x

l = [1, 2, 3, 3]
for index, elmnt in gen(l):
    # do stuff
    print(index, elmnt)
# 0 1
# 2 3
# 3 3
# 1 2

答案 1 :(得分:1)

shuffle列表一次然后pop()返回最后一个元素,减少列表。

>>> from random import shuffle
>>> a=[1,2,3,3]
>>> shuffle(a)
>>> a.pop()
3
>>> a.pop()
2
>>> a.pop()
3
>>> a.pop()
1

编辑:使用enumerate

跟踪索引
from random import shuffle
a=[1,2,3,3]
b=list(enumerate(a))
shuffle(b)
b.pop()

(3, 3)

docs:enumeraterandom.shuffle

答案 2 :(得分:0)

您可以使用random.sample。

random.sample(population, k)

返回从总体序列或集合中选择的唯一元素的k长度列表。用于无需替换的随机抽样。

答案 3 :(得分:0)

使用@ thanasisp的解决方案并使用shufflezip来跟踪索引:

a = range(10, 15)
b = zip(a, range(len(a))) # pairs of values and indices

import random
random.shuffle(list(b)) # list() evaluates the zip

a_shuffle, idxes = list(zip(*b))
# e.g. [(13, 11, 10, 14, 12), (3, 1, 0, 4, 2)]