有没有办法创建一个小于10,000的所有数字的列表,不包含任何数字0,2,4,5,6,8?当然,人们可以简单地输入类似的内容:
bads = ['0', '2', '4', '5', '6', '8']
goods = []
for n in range(1, 10000, 2):
if not any(bad in str(n) for bad in bads):
goods.append(n)
但是,我正在寻找一种方法,而不是考虑数字1,3,7,9,并创建所有可能的唯一字符串排列,这些数字大小为4或更小,允许重复数字。例如,itertools是否有一些容易做到这一点的东西?我查看了排列方法,但这并没有产生带有重复数字的数字,而且产品方法似乎也不是我追求的,因为它只会返回1,3的笛卡尔积,5,7与自己。
答案 0 :(得分:0)
这是一种使用来自itertools的permutations
和combinations_with_replacement
的简单方法:
from itertools import permutations, combinations_with_replacement
def digit_combinations(power_of_ten):
numbers = set()
for n in range(1, power_of_ten + 1):
for combination in combinations_with_replacement("1379", n):
numbers |= set(permutations(combination, len(combination)))
return sorted(int(''.join(number)) for number in numbers)
print(digit_combinations(4))
<强>输出强>
[1, 3, 7, 9, 11, 13, 17, 19, ..., 9971, 9973, 9977, 9979, 9991, 9993, 9997, 9999]
使用发电机可以提高空间效率,但根据范围,它可能不值得。 (对于最多10,000个,只有340个数字。)对于10 ^ 4的数字,此代码大致与您的简单示例一样长。但对于10 ^ 7,这个代码在我的系统上的运行速度比简单的例子快40倍。
你能否包括你对发电机的想法?
这是上面代码对生成器形式的基本修改:
from itertools import permutations, combinations_with_replacement
def digit_combinations_generator(power_of_ten):
for n in range(1, power_of_ten + 1):
for combination in combinations_with_replacement("1379", n):
for number in set(permutations(combination, len(combination))):
yield int(''.join(number))
generator = digit_combinations_generator(4)
while True:
try:
print(next(generator), end=', ')
except StopIteration:
print()
break
这不返回已排序的数字,它只是在生成它们时将它们移出。