擅长:python、mysql、java
<p><a href="https://stackoverflow.com/a/54120743/364696">Selcuk's answer</a>是解决您的问题的最佳方法,但我认为我应该提供一种替代方法,当<code>range</code>很大,而<code>oldNumbers</code>不太大时,这种方法会更有效。你知道吗</p>
<pre><code>from itertools import islice
from random import sample
forbidden = set(oldNumbers)
numneeded = 5
# Might have old numbers in it, but definitely has at least 5 new numbers
numbers = random.sample(range(1, 39), numneeded + len(forbidden))
# Generates only the new numbers
notForbidden = (num for num in numbers if num not in forbidden)
# Keep only as many as you need
newNumbers = list(islice(notForbidden, numneeded))
</code></pre>
<p>所有这些(除了导入)都可以是一行(<code>newNumbers = list(islice(filterfalse(set(forbidden).__contains__, random.sample(range(1, 39), 10)), 5))</code>),但我将其拆分以供说明。你知道吗</p>
<p>这样做的好处是不需要构造一个经过过滤的<code>list</code>来传递给<code>sample</code>,如果<code>range</code>变大,可能会成为运行时/内存的问题。取而代之的是,你只需要生成足够的数字,你就可以确定你至少已经生成了你需要的数量,即使你碰巧选择了所有禁止的数字,然后只保留需要的数量。你知道吗</p>
<p>Selcuk的答案是<code>O(n)</code>是<code>range</code>的大小,这个答案是<code>O(n)</code>你需要生成的数加上要排除的数(由于明显的原因,它应该总是小于<code>range</code>的大小)。你知道吗</p>