Python 如何让我的程序随机且仅一次列出列表中的每个项目

Python 如何让我的程序随机且仅一次列出列表中的每个项目,python,list,random,Python,List,Random,我正在尝试使用一个函数,它使用随机导入从列表[0,1,2,3,4,5,6,7,8]中随机选择一个值,打印该值,然后重复它自己,直到所有的数字都被选中。我遇到的问题是,确保当它重复出现时,不会再次选择该数字。我试过的是: def ListArranger(): randomPick = random.choices(list) if len(list) > 0: if list[randomPick] != " ":

我正在尝试使用一个函数,它使用随机导入从列表[0,1,2,3,4,5,6,7,8]中随机选择一个值,打印该值,然后重复它自己,直到所有的数字都被选中。我遇到的问题是,确保当它重复出现时,不会再次选择该数字。我试过的是:

def ListArranger():
    randomPick = random.choices(list)
    if len(list) > 0:
        if list[randomPick] != " ":
            print(list[randomPick])
            list[randomPick] = " "
            ListArranger()
        else:
            ListArranger()

我遇到了一个问题,列表索引必须是整数或片,而不是列表。我假设它有问题,因为我试图将列表值设置为字符串,但我不知道如何解决这个问题。如果您将列表视为一个堆栈,您只需将
shuffle()
一次,然后将
pop()
每个元素按顺序清除,直到完成为止

此外,这是一个使用发电机的机会。只需添加一个
yield
,即可将任何函数转换为生成器。然后可以在
for
语句中使用它

我们的输入列表保持不变,因为我们在内部
copy()
it

from random import shuffle

def chooseOneWithoutReplace(items):
    data = items.copy()
    shuffle(data)
    while data:
        yield data.pop()
    # nothing more to yield
    # generator ends -> outer for loop ends

daysOfWeek = [1,2,3,4,5,6,7]
for i in chooseOneWithoutReplace(daysOfWeek):
    print(i)
输出

1
4
5
3
7
2
6

使用
shuffle
,它仅对给定序列执行此操作

def listArranger(a):
    random.shuffle(a)
    for item in a:
        print(item)
不要用局部变量来隐藏内置名称:
list
可能是最常见的坏的变量名称


将列表传递到函数中,而不是假设它是外部作用域。

错误来自行
3,4,5

因为您正在用所有这些行中的列表为列表编制索引。 randomPick是一个列表,而不是错误指示的整数或切片

示例:
打印(随机选择[**[1,2,3,4]**]
这是实际问题

只能通过整数或切片对列表进行索引

解决方案:

import random

lst = [1,2,3,4,5,6,7,8]
check_lst = []

while True:
    random_num = random.choice(lst)
    
    if random_num in check_lst:
        continue
    elif random_num not in check_lst:
        check_lst.append(random_num)
        print(random_num)
    
    if len(lst) == len(check_lst):
        print("Finish the loop")
        break
您可以将给定列表复制一次(引用自:“所有切片操作返回一个包含请求元素的新列表。”),并从()生成无序列表

来自随机导入洗牌
def列表安排器(lst):
lst_copy=lst[:]
洗牌(第一次拷贝)
从lst_拷贝获得的收益
您可以迭代此函数,它将在每次从
lst
返回新的随机元素时返回您

如果不需要保持源列表不变,则可以省略复制、无序移动列表本身并对其进行迭代。

以下是解决方案:

import random

def ListArranger(list):
    if len(list) > 0:
        randomPick = random.choice(list)
        print(randomPick)
        list.remove(randomPick)
        ListArranger(list)

list = [0,1,2,3,4,5,6,7,8]
ListArranger(list)
输出:

2
8
7
1
3
4
0
5
6
此函数将列表作为参数,并调用自身,直到列表为空


它在每次递归调用中删除列表中的一个随机元素,同时打印出删除的元素。

似乎没有人提到的明显选择是:


使用
返回lst.pop(随机选择(len(lst)))
返回给定集合中的随机项并将其从此集合中删除。请参阅。返回到
随机
文档并查找
shuffle
。您还可以返回
lst\u copy
。该列表已存在于内存中,并提供生成器的所有功能。而且对于cli来说,它非常便宜把一个列表转换成一个生成器是很困难的,但反过来又很昂贵。不用说,使用内置的shuffle方法比使用random.choice进行暴力强制更有效。但是,我假设问题是试图教新手如何在不实际使用内置方法的情况下复制shuffle的结果@schwobaseggl,检查答案中的最后一句;-)另外,我只想使用语句中的收益率,这是可以应用它的罕见次数之一。Ofc,我可以按照你的建议返回
iter(lst\u copy)
lst\u copy
本身。@pakpe然后还有一些众所周知的线性方法可以做到这一点。这可能是最好的解决方案,非常简单。学习一些新东西很好。我相信NF正试图递归地解决这个问题。您的迭代解决方案有效。考虑改变它,同时变为真,而LEN(LST)> LEN(CHECK-LST)。然后,您只需要中间条件(当前为elif…),并且可以摆脱其他两个条件。社区鼓励在代码中添加解释,而不是纯粹基于代码的答案(请参阅)。
def ListArranger(lst):
    return random.sample(lst, len(lst))

for pick in ListArranger(range(9)):
    print(pick)

4
0
8
1
2
3
7
6
5
import random
lst=[0,1,2,3,4,5,6,7,8]
lstlen=len(lst)
def ListArranger():
    if len(lst)!=0:
        randomPick=random.choice(lst)
        print(randomPick)
        lst.pop(lst.index(randomPick))
        ListArranger()
    else:
        for i in range(lstlen):
            lst.append(" ")
            
ListArranger()