以可变基数向上计数 python

Count upward in python with variable base

我想知道如何实现 python 中范围函数的等效功能,但能够指定基数。例如:

countUp(start=0, end=1010, base=2)
countUp(start=0, end=101, base=3)
countUp(start=0, end=22, base=4)

基数 2 计数的示例输出:

[0, 1, 10, 11, 100, ...]

我是否缺少执行此操作的功能?或者我可以做什么?

您不能创建具有特殊基数的整数,但您可以在字符串的指定基数中创建您期望的数字:

def my_range(start,end,base,step=1):

    def Convert(n,base):
       string = "0123456789ABCDEF"
       if n < base:
          return string[n]
       else:
          return Convert(n//base,base) + string[n%base]
    return (Convert(i,base) for i in range(start,end,step))

演示:

print list(my_range(4,20,2))
['100', '101', '110', '111', '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111', '10000', '10001', '10010', '10011']

请注意,传递给函数的字符串 string = "0123456789ABCDEF" 将一直有效到基数 16,如果要计算更大的基数,可以使用更多字母。

您可以使用自定义迭代器来完成:

我从 here and the base conversion from here

中获取了迭代器代码
import string
class BaseRange:
    def __init__(self, low, high, base):
        digs = string.digits + string.letters
        self.current = low
        self.high = high
        self.base = base
    def __iter__(self):
        return self
    def next(self):  # Python 3 requires this to be __next__
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 1
            return self.int2base(self.current - 1, self.base)
    def int2base(self, x, base):
        if x < 0: sign = -1
        elif x == 0: return digs[0]
        else: sign = 1
        x *= sign
        digits = []
        while x:
            digits.append(digs[x % base])
            x /= base
        if sign < 0:
            digits.append('-')
            digits.reverse()
        return ''.join(digits)

几个示例运行产生:

>>> for c in BaseRange(0, 10, 2):
    print(c)


0
1
01
11
001
101
011
111
0001
1001
0101
>>> for c in BaseRange(0, 10, 3):
    print(c)


0
1
2
01
11
21
02
12
22
001
101

你显然混淆了数字和数字的表示。

一个数字没有底数...它是有底数的数字表示...例如,以 2 为底数表示为“101”的数字是与以 10 为基数的“5”表示的数字相同。

range 函数将对连续的数字进行计数,您可以通过以下方式在您喜欢的任何基数中获得它们的表示形式:

digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

def int2str(x, base):
    if x < 0:
        return "-" + int2str(-x, base)
    return ("" if x < base else int2str(x//base, base)) + digits[x % base]

您可以使用 itertools product 函数来完成此操作。

from itertools import product

def countUp(start, end, base):
    n_digits = len(end)
    combs = product(*[range(base)] * n_digits)
    while (n := next(combs)) <= end:
        yield n

list(countUp(start=0, end=(2, 0), base=3))
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)]