以单调递增的顺序编写整数序列的Pythonic方法

时间:2013-05-02 15:11:22

标签: python

110**6的整数编写的pythonic和有效方法是什么?数字处于单调递增的顺序?

例如: (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)]

6 个答案:

答案 0 :(得分:3)

这会返回max_digits=6的8001个数字:

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等)并且转换为数字,则必须检查它们。

答案 1 :(得分: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) ]

答案 2 :(得分: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的整数。

当然,我们希望反向排序orde中的数字,而不是排序顺序,这就是我们反转每个结果的原因。但这会使列表排除顺序,因此我们对结果进行排序。

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

答案 3 :(得分: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))

答案 4 :(得分: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

答案 5 :(得分: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())