2

将整数从数字以单调递增的顺序1写入的pythonic和有效的方法是什么?10**6

例如: (1,2,3,4,5,6,7,8,9,10,11,20,21,22,30,31,32,33,...)

这完成了工作,但看起来很丑陋。

nums = [10**0*k6 for k6 in range(1,10)] +
       [10**1*k5 + 10**0*k6 for k5 in range(1,10) for k6 in range(k5+1)] + 
       [10**2*k4 + 10**1*k5 + 10**0*k6 
        for k4 in range(1,10) for k5 in range(k4+1) for k6 in range(k5+1)] +
       [10**3*k3 + 10**2*k4 + 10**1*k5 + 10**0*k6
        for k3 in range(1,10) for k4 in range(k3+1) for k5 in range(k4+1) for k6 in range(k5+1)] +
       [10**4*k2 + 10**3*k3 + 10**2*k4 + 10**1*k5 + 10**0*k6
        for k2 in range(1,10) for k3 in range(k2+1) for k4 in range(k3+1) for k5 in range(k4+1) for k6 in range(k5+1)] +
       [10**5*k1 + 10**4*k2 + 10**3*k3 + 10**2*k4 + 10**1*k5 + 10**0*k6
        for k1 in range(1,10) for k2 in range(k1+1) for k3 in range(k2+1) for k4 in range(k3+1) for k5 in range(k4+1) for k6 in range(k5+1)]
4

6 回答 6

3

这将返回 8001 个数字max_digits=6

def ascending(ndig, first_digit_max):
    for x in xrange(0, first_digit_max+1):
        if ndig == 1:
            yield [x]
        else:
            for y in ascending(ndig-1, x):
                yield [x] + y

max_digits = 6
nums = sorted([int(''.join(map(str, num)))
               for ndig in xrange(1, max_digits+1)
               for num in ascending(ndig, 9)
               if any(num)])

ascending产生ndig数字列表,其中第一个数字小于或等于first_digit_max. 它以递归方式工作,因此如果用ndig=6调用它,它会用 调用自身ndig=5,等等,直到它用ndig=1返回单个数字的位置调用自身。这些是列表,因此必须检查它们是否有任何数字不为零(否则它也会返回 0、00、000 等)并将其转换为数字。

于 2013-05-02T15:24:37.570 回答
2
def gen(size_digits):
        if size_digits == 0:
            return ( i  for i in range(10) ) 
        else:
            return ( new_dig*(10**size_digits) + old_digit  for old_digit in gen(size_digits-1) for new_dig in range(10) if  new_dig <  int(str(old_digit)[0])   )



l = [ num for num in gen(6) ]
于 2013-05-02T15:34:32.097 回答
1

这是一个(几乎)单行:

from itertools import combinations_with_replacement
from string import digits

lst = sorted(set(int('0' + ''.join(reversed(e))) 
             for e in combinations_with_replacement([''] + list(digits), 6)))[1:]    
print lst

这个怎么运作

digits是字符串0123456789combinations_with_replacement创建所有可能的排序数字组合。通过添加空字符串,我们得到每个大小小于或等于 6 的排序整数。

当然,我们想要反向排序的数字,而不是排序顺序,所以这就是我们反转每个结果的原因。但这会使列表无序,因此我们对结果进行排序。

此外,我们使用空字符串的技巧会导致包含一些重复项(不是很多),因此我们使用 set() 来删除它们。

于 2013-05-02T16:04:18.067 回答
0

我还没有完全弄清楚为什么会这样,但预期的方法是取一个数字,并将其附加到我们已经生成的所有可以匹配的数字上——这可以通过查看最右边的数字来决定号码。

length = 6

digits = range(10)

numbers = digits[1:]
for curNumber in numbers:
    for n in range(1 + curNumber%10):
        numbers.append(curNumber*10 + n)
    if(curNumber == 99999):
        break

print numbers
于 2013-05-02T16:18:41.857 回答
0

只是这样做可能最终会更有效率(性能方面):

def xfn():
    x, i = [9], 0

    while True:
        if i == len(x) - 1:
            x.insert(i, 0)

        if x[i] < x[i+1]:
            x[i] += 1
            x[0:i] = [0] * i
            i -= 1
            yield int(''.join(map(str, reversed(x[0:-1]))))
            continue

        i += 1

itertools.takewhile(lambda x: x < 10 ** 6, xfn())
于 2013-05-02T16:55:44.730 回答
0

你想变得多高效?

[i for i in range(10**6) if str(i) == ''.join(sorted(str(i), reverse=True))]

使用itertools

from itertools import combinations_with_replacement
from string import digits
sorted(int(''.join(reversed(t)))
       for n in range(6)
       for t in combinations_with_replacement(digits, n)
       if not all(d == '0' for d in t))
于 2013-05-02T15:29:30.100 回答