【问题标题】:Random generator that removes items from a list after picking选择后从列表中删除项目的随机生成器
【发布时间】:2022-05-14 00:52:13
【问题描述】:

我有一个包含 48 个项目的列表。我想随机挑选其中 3 个项目,然后从列表中删除这三个项目。之后,随机挑选3个新物品。我希望循环 16 次,直到所有项目都被删除。

我尝试了一个 for 循环。但我不知道如何删除从列表中随机选择的那些特定项目。我对 Python 和编程都很陌生。非常感谢您的帮助。

list_ = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8

loop_ = np.arange(0, 16)

for i in loop:
    print(random.sample(list_, 3))

【问题讨论】:

  • 注意,你不应该在 python 类型、内置插件等之后命名你的变量
  • 使用list 作为变量的名称不是一个好主意。你破坏了同名的内置函数

标签: python random


【解决方案1】:

np.arange(1,16) 的长度为 15,但您想循环 16 次。此外,当列表中有重复项时,请避免使用 list.remove,即使它可能不会对您的特定问题造成麻烦。最后,如前所述,避免使用“列表”作为名称,因为它已经被 Python 使用。 这是我的建议,处理索引并使用 list.pop(0) 方法:

l = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8

for i in range(16):
    item = random.sample(range(len(l)), 3)
    for k in sorted(item, reverse=True):
        l.pop(k)

print(l)
#[]

【讨论】:

    【解决方案2】:

    您可以使用list.remove() 方法:

    import numpy as np
    import random
    
    list = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8
    
    loop = np.arange(1,16)
    
    for i in loop:
        item = random.sample(list, 3)
        print(item)
        for i in item:
            list.remove(i)
    

    请注意,将变量命名为已赋予内置函数的名称(例如 list)被认为是一种不好的做法。最好将您的列表命名为其他名称,例如,colors

    import random
    
    colors = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8
    
    for i in range(0, len(colors), 3):
        item = random.sample(colors, 3)
        print(item)
        for i in item:
            colors.remove(i)
    

    更新

    正如@dawg 所指出的,list.remove() 方法总是从最靠近列表开头的列表中删除项目,从而消除了随机性的概念。

    我意识到使用索引而不是值会更准确,所以使用list.pop() 而不是list.remove()

    from random import randint
    
    colors = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8
    
    while colors:
        lst = [colors.pop(randint(0, len(colors) - 1)) for _ in range(3)]
        print(lst)
    

    【讨论】:

    • 由于 OP 有一个较小的列表乘以一个更大的列表,.remove 方法可能会删除与采样的不同的项目。它真的应该通过索引来完成del
    • 另外np.arange(1,16) 的长度为15
    • @dawg 嘿,谢谢!是的,我犯了严重的错误是我的错,对此感到抱歉。
    • @IoaTzimas 你是对的,谢谢 :) 但我相信这是 OP 代码的一个小错误。
    • @Henrik 当循环中不使用迭代的值时,使用下划线比将迭代的每个值(如i)分配给变量更有效。跨度>
    【解决方案3】:

    你也可以使用 list.pop(index) 方法。

    import random as rd
    import numpy as np
    lst = ['Pink', 'Red', 'Green', 'Darkgreen', 'Blue', 'Skyblue'] * 8
    loop = np.arange(1,16)
    for i in loop:
        for k in range(0,3):
            item = lst.pop(rd.choice(range(0,len(lst))))
            print(item)
    

    .pop(index) 方法做了两件事。它返回列表给定索引处的元素。然后它从列表中删除该元素。

    在 .pop() 函数内部,我们有以下内容:随机选择一个数字(即索引),该选择是一个介于 0 和列表长度(不包括)之间的数字列表。

    【讨论】:

    • np.arange(1,16) 长度为 15
    • 我只是尽可能简单地保留原始海报中的内容。不要告诉我它的长度是 15,告诉 OP 它是。
    【解决方案4】:
    import random
    
    my_list = [
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
        18, 19, 20, 21, 22, 23, 24, 25,26, 27, 28, 29, 30, 31, 32,
        33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48
    ]
    
    for i in range(16):
        removed_list = random.sample(my_list, 3)
        for item in removed_list:
            my_list.remove(item)
            
    print(my_list)
    

    【讨论】:

    • 欢迎来到 Stack Overflow!请参阅 dawg 的this 评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 2020-07-01
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多