显示随机选择(Python)

4 投票
5 回答
15530 浏览
提问于 2025-04-15 17:41

我有一个物品列表(list[]),我想从中随机显示一个物品,但这个显示的物品在最近的x次请求中不能重复出现超过一次。

  1. 列表1 = 物品1, 物品2, 物品3, 物品4, 物品5, 物品6, 物品7, 物品8, 物品9, 物品10
  2. 从上面的列表中随机选择一个物品进行显示
  3. 列表2 = 存储最近显示的物品,列表2只应该存储7个物品,不能更多
  4. 从列表中随机选择一个物品,但要确保这个物品不在列表2中

这样做对吗?无论如何,我想知道如何限制一个列表只存储7个物品?

谢谢

5 个回答

2

你可以试试用生成器函数,每当你需要一个新项目的时候,就调用一下 .next()

import random
def randomizer(l, x):
    penalty_box = []
    random.shuffle(l)
    while True:
        element = l.pop(0)
        # for show
        print penalty_box, l
        yield element
        penalty_box.append(element)
        if len(penalty_box) > x:
            # penalty time over for the first element in the box
            # reinsert randomly into the list
            element = penalty_box.pop(0)
            i = random.randint(0, len(l))
            l.insert(i, element)

使用示例:

>>> r = randomizer([1,2, 3, 4, 5, 6, 7, 8], 3)
>>> r.next()
[] [1, 5, 2, 6, 4, 8, 7]
3
>>> r.next()
[3] [5, 2, 6, 4, 8, 7]
1
>>> r.next()
[3, 1] [2, 6, 4, 8, 7]
5
>>> r.next()
[3, 1, 5] [6, 4, 8, 7]
2
>>> r.next()
[1, 5, 2] [4, 3, 8, 7]
6
>>> r.next()
[5, 2, 6] [4, 3, 8, 7]
1
>>> r.next()
[2, 6, 1] [5, 3, 8, 7]
4
>>> r.next()
[6, 1, 4] [3, 8, 2, 7]
5
4

这就是你想要的吗?

list1 = range(10)
import random
random.shuffle(list1)
list2 = list1[:7]
for item in list2:
    print item
print list1[7]

换句话说,看看 random.shuffle() 这个函数。如果你想保持原来的列表不变,可以先复制一份:list_copy = list1[:]

7

在Python中,collections.deque是唯一一种自然支持限制大小的序列类型(这只在Python 2.6及以上版本中可用)。如果你使用的是Python 2.6或更新的版本:

# Setup
from collections import deque
from random import choice
used = deque(maxlen=7)

# Now your sampling bit
item = random.choice([x for x in list1 if x not in used])
used.append(item)

如果你使用的是Python 2.5或更早的版本,就不能使用maxlen这个参数,你需要多做一步操作来去掉deque前面的元素:

while len(used) > 7:
    used.popleft()

这种方法虽然不是最高效的,但可以用。如果你需要更快的速度,并且你的对象是可哈希的(大多数不可变类型),可以考虑用字典来代替“已使用”列表。

另外,如果你只需要做一次这样的操作,random.shuffle方法也可以用。

撰写回答