Python:生成不在列表中的随机整数

4
我对Python(以及编程)非常陌生。 我正在尝试创建一个函数,该函数将创建列表的副本,并将任何字符串“rand”的实例替换为随机整数。 该函数将被多次调用,每次使用新的input_list。这些新项目应附加到现有的输出列表中。我们可以假设不会重复出现整数,但“rand”字符串可能会多次出现。 这是我的当前代码。它非常接近我想要的,但当随机数已经在列表中时,它只是继续进行下一个项目,而不是尝试创建新的随机数。 有人能帮我吗? 提前谢谢您。
import random
input_list = [1, 3, "rand", 2]
def number_adder(input_list):
  output_list = []

  for item in my_list:
    if item == "rand":
      new_variable = int(random.randint(0, 4))
      if new_variable in output_list:
        continue
    else:
      new_variable = item

  output_list.append(new_variable)
return output_list

2
你能否提供一个具体的示例,展示一个输出列表与你预期不同的情况,并且说明你实际想要达到的结果是什么? - mkrieger1
1
当函数完成时,它将接收一个新的输入列表。然后将该列表附加到相同的输出列表中。请通过示例说明,因为我不确定确切含义。例如:假设有一个函数,用于将两个列表相加并返回结果。现在我们有两个输入列表[1,2,3]和[4,5,6]。如果我们按顺序调用函数两次,并将结果存储在同一个输出列表中,那么输出列表将包含[1,2,3,4,5,6]和[1,2,3,4,5,6]。 - glibdud
3
当你想检查相等性时,应该使用 ==,例如 if item == "rand" - kingJulian
1
@RyanLague 你有没有注意到你把一个数字/字符串赋值给了一个列表 (output_list = item)? - noamgot
语法错误:'return'在函数外部。修复后:名称错误:名称'my_list'未定义-为什么不在询问我们之前测试您的代码?此外,您没有调用您的函数。 - Stefan Pochmann
显示剩余3条评论
3个回答

2
import random

input_list = [1, 3, "rand", 2]
output_list = []

options = set(range(5))
for item in input_list:
  if item == "rand":
    new_variable = random.choice(list(options))
  else:
    new_variable = item
  output_list.append(new_variable)
  options -= set([ new_variable ])

你可以这样做。但如果没有可能的随机数可用,那么这将引发异常。
它将保持剩余选项的set,每当新值添加到输出列表中时就会减少。每当需要随机数时,它将使用choice从该set中取出一个随机元素。这样,您不必使用循环重复调用随机函数,直到找到有效的随机数。
一开始可能会觉得循环是可行的,直到您遇到更大的数字,因此您必须重试很多次才能找到有效的随机数(例如,在99990个元素的列表中randint(0, 100000))。这将不必要地减慢代码速度。
实际上,我想稍微改写一下代码,使用生成器:
def fill_randoms(list_with_randoms, options):
  for item in list_with_randoms:
    value = random.choice(list(options)) if item == 'rand' else item
    yield value
    options -= set([ value ])

我会这样调用它:

list(fill_randoms([1, 3, "rand", 2], set(range(5))))

但如果您不熟悉生成器,还是使用其他代码更好。


你选择range(5)作为options变量的原因是因为列表中有4个项目吗?len(input_list) + 1会是一样的吗? - Ryan Lague
1
random.randint(0,4) 会返回集合 (0,1,2,3,4) 中的值。而 range(5) 同样包含这些值。 - Alfe
如果你总是把集合转换成列表,使用集合的意义何在? - Stefan Pochmann
我想一直从中删除值。在集合中查找项比在列表中更便宜,因为它们被散列了。而且我只需要将其转换为列表,因为random.choice()太愚蠢了,无法接受一个set(实际上应该可以)。主要原因是:它逻辑上是一个集合。其中的值没有顺序。为了反映这一点,请使用set - Alfe
我不在乎。为了从集合中获取单个随机元素,没有必要将其构建成完整的列表。迭代到第 random-th 个元素应该足够了,例如(仍然比构建列表便宜得多)。我在Python中实现了这个测试,在那里它比现有版本慢。根据集合的内部工作原理,通过某些特定于该类型集合固有的算法,可能也可以等概率地获取一个元素。 - Alfe
显示剩余5条评论

1

当数字在输出列表中时,循环:

if item == "rand": 
    new_variable = int(random.randint(0, 4))
    while new_variable in output_list:
        new_variable = int(random.randint(0, 4))

在Python中,=运算符不是比较运算符。如果你想让你的代码不出错,你需要使用==或其他已有的运算符。 - HolyDanna
@StefanPochmann 是的,你说得对。我已经纠正了错误,即使OP似乎有他的要求,也让它保持不变。 - AlEmerich
1
是的,现在看起来没问题了。虽然我会使用 while Truebreak 来避免代码重复。 - Stefan Pochmann

1

我修复了评论中指出的错误。 这里有两个函数满足你的要求:

import random
input_list = [1, 3, "rand", 2]

def rand_replacer(my_list):
    output_list = []
    for item in my_list:
        if item == "rand":
            while True:
                new_variable = random.randint(0, 4)
                if new_variable not in my_list:
                    output_list.append(new_variable)
                    break
        else:
            output_list.append(item)
    return output_list

太棒了。谢谢!我会在短期内使用你的第一个函数,因为它符合我的当前知识水平,并且也会研究numpy。 - Ryan Lague
1
如果第一个解决方案选择的随机数已经存在于输出中,它将对输出没有任何价值。我认为这不是你想要的。第二个(numpy)不会检查输出列表中已经存在的随机数。所以两者都有缺陷。 - Alfe
我现在正在进行实验,@Alfie,你是正确的。 - Ryan Lague

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接