首页 > 解决方案 > 在python中遵循数字规则的所有可能数字的组合

问题描述

寻找一种“pythonish”和简单的方法来实现按照不同数字范围生成所有可能的数字。

示例:生成字符串(表示数字),数字“01234567”的出现次数范围为[0-4],“8”的出现次数范围为[0-10],“9”的出现次数为[0-100]
生成的数字示例:{' 11337899999999', '33567899999999', '245678999999999999999',...}
(所有生成的数字都应该是连续数字......所以'88119'无效)

到目前为止,我想出了一个非常简单和干净的代码,但是不完全符合我的需要:

from itertools import combinations_with_replacement
length = 50
for x in combinations_with_replacement('0123456789', length):
   print("".join(x), end=', ')

这将生成我需要的数字,但也会生成一堆不必要的数字,这将大大延迟执行。

考虑根据规则逐个生成数字并连接......但相信这将是一个“肮脏”的解决方案并且效率低下。
任何人都知道这样做的好方法吗?(欢迎使用 Itertools 或任何其他库)

标签: pythongeneratorcombinationsitertools

解决方案


所以,我最终选择了 itertools.combinations_with_replacement 并将其更改为接受包含最大使用数字的数组......非常简单,但它正在工作。

如果有人对如何以不同的方式看待它或调整任何东西以加快速度有任何提示,我会很高兴的。

def combinations_with_replacement2(iterable, m_digits, r):
    pool = tuple(iterable)
    n = len(pool)
    if not n and r: return
    count = [0] * n
    indices = [0] * r
    d = 0
    for i in range(r):
        if count[d] == m_digits[d]: d += 1

    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != n - 1: break
        else: return

        count = [0] * n
        d = indices[i] + 1
        for f in range(i, r):
            indices[f] = d
            count[d] += 1
            if count[d] == m_digits[d]: d += 1

        yield tuple(pool[i] for i in indices)

推荐阅读