显示随机选择 (Python)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2011583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:33:36  来源:igfitidea点击:

Display random choice (Python)

pythonlistrandomlimit

提问by eozzy

I have a list[] of items from which I'd like to display one randomly, but the displayed item must not repeat more than once in last x requests.

我有一个项目列表 [],我想从中随机显示一个项目,但显示的项目在最近的 x 次请求中不能重复多次。

  1. list1 = item1, item2, item3, item4, item5, item6, item7, item8, item9, item 10
  2. Display a random selection from the list above
  3. list2 = store the last displayed item in list2 which should only store 7 items, not more
  4. Display a random selection from the list but make sure it doesn't exist in the list2
  1. list1 = item1, item2, item3, item4, item5, item6, item7, item8, item9, item 10
  2. 显示上面列表中的随机选择
  3. list2 = 将最后显示的项目存储在 list2 中,它应该只存储 7 个项目,而不是更多
  4. 显示列表中的随机选择,但确保它不存在于列表 2 中

Is that the right way to do it? Either way, I'd like to know how to limit a list to store only 7 items?

这是正确的做法吗?无论哪种方式,我都想知道如何将列表限制为仅存储 7 个项目?

Thanks

谢谢

回答by Crast

collections.deque is the only sequence type in python that naturally supports being bounded (and only in Python 2.6 and up.) If using python 2.6 or newer:

collections.deque 是 python 中唯一自然支持有界的序列类型(并且仅在 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)

If using python 2.5 or less, you can't use the maxlen argument, and will need to do one more operation to chop off the front of the deque:

如果使用 python 2.5 或更低版本,则不能使用 maxlen 参数,并且需要再执行一项操作来切掉 deque 的前面:

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

This isn't exactly the most efficient method, but it works. If you need speed, and your objects are hashable (most immutable types), consider using a dictionary instead as your "used" list.

这并不是最有效的方法,但它确实有效。如果您需要速度,并且您的对象是可散列的(大多数不可变类型),请考虑使用字典作为“已使用”列表。

Also, if you only need to do this once, the random.shuffle method works too.

此外,如果您只需要执行一次,random.shuffle 方法也可以。

回答by Alok Singhal

Is this what you want?

这是你想要的吗?

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

In other words, look at random.shuffle(). If you want to keep the original list intact, you can copy it: list_copy = list1[:].

换句话说,看看random.shuffle()。如果你想保持原始列表完整,你可以复制它:list_copy = list1[:]

回答by tkerwin

You could try using a generator function and call .next()whenever you need a new item.

您可以尝试使用生成器函数并.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)

Usage example:

用法示例:

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

回答by Teddy

I'd use set objects to get a list of items in list1 but not in list2:

我会使用 set 对象来获取 list1 中但不在 list2 中的项目列表:

import random

list1 = set(["item1", "item2", "item3", "item4", "item5",
             "item6", "item7", "item8", "item9", "item10"])
list2 = []
while True:  # Or something
    selection = random.choice(tuple(list1.difference(set(list2))))
    print(selection)
    list2.append(selection)
    if len(list2) > 7:
        list2 = list2[-7:]

回答by Sapph

Something like:

就像是:

# Setup
import random
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = []

# Loop for as long as you want to display items
while loopCondition:
    index = random.randint(0, len(list1)-1)
    item = list1.pop(index)

    print item

    list2.append(item)
    if(len(list2) > 7):
        list1.append(list2.pop(0))