【问题标题】:Range between two tuples of integers?两个整数元组之间的范围?
【发布时间】:2013-07-07 23:51:49
【问题描述】:

元组似乎非常适合版本号比较(假设只有数字元素,在我的例子中是给定的)。我有两个由整数组成的元组形式的版本号。假设这些元组是:

minver = (1,2,3)
maxver = (1,2,9)

有没有一种简单而优雅的方法来获得从minvermaxver 的“范围”作为list? IE。对于上述情况,我想得到一个像这样的list

[(1,2,3), (1,2,4), (1,2,5), (1,2,6), (1,2,7), (1,2,8), (1,2,9)]

(注意:如果列表中缺少最后一个元素也可以,即如果返回的范围包含最大值。)

range 函数显然不起作用(需要整数),但我也不想依赖元组恰好是 x 元素(在上述情况下,x = 3)。

例如,如果我有一个 minver tuple (1,) 如果 maxver tuple 包含三个值/元素(例如 (1,2,3)),则它应该被视为 (1,0,0)

任何以 Python 方式执行此操作的方式(即优雅)?

【问题讨论】:

  • 所以编辑引出了一个问题:(1, 2)(1, 3, 1) 之间的范围是多少(例如)
  • @JonClements: aaaah ... 现在我明白你的意思了... :) ... 很好,甚至没有想到这一点。让我们假设已知最大值,现在假设它是9。你的回答让我开始了,我认为。目前正在修修补补。
  • 我也在调整 ;)
  • 好的 - 存在另一个不限于 0-9 的答案 - 比我认为的旧答案要好一些
  • 如果仍然感兴趣 - 另一个应该更快的答案(当然,如果与您相关):)

标签: python-2.7 range tuples


【解决方案1】:

好的 - 现在是凌晨 2:30,所以原则是您固定任何版本的最大长度和上限,然后将其视为数字的基础...将您的开始和结束转换为 int作为一个范围,然后有另一个函数来转换回元组......需要一些工作,但相当合理的理论......

from itertools import izip_longest, chain

minver = (1, 1, 3)
maxver = (1, 3, 19)

def version_range(start, end):
    start, end = zip(*izip_longest(start, end, fillvalue=0))
    base = max(max(chain(start, end)), 9) + 1
    def _toint(seq, base):
        return sum(base ** n * val for n, val in enumerate(reversed(seq)))
    def _totuple(num, base, length):
        ret = []
        for n in (base ** i for i in reversed(range(length))):
            res, num = divmod(num, n)
            ret.append(res)
        return tuple(ret)
    for se in xrange(_toint(start, base), _toint(end, base) + 1):
        print _totuple(se, base, len(start))


version_range(minver, maxver)

【讨论】:

    【解决方案2】:

    为了平衡,这里是凌晨 3:00 :)

    我认为无需电源** 操作就可以实现这一点,这对于大数字来说可能会变得昂贵。

    我已经为 python 3 编写了这段代码,但它可以很容易地用于 python 2.7。

    原则是简单地生成新版本,直到我们达到最大值。

    代码如下:

    # Easier to work with lists (for me)
    min_ver = [1,1,2]
    max_ver = [2,3,4]
    
    max_num = max(min_ver + max_ver)
    orig_length = len(min_ver)
    
    
    def increase(an_array, max_num):
        while an_array[-1] == max_num:
            an_array.pop()
        an_array[-1] += 1
        an_array += [0] * (orig_length - len(an_array))
        return an_array
    
    
    def gen_range(start, end, max_num):
        while start != end:
            yield increase(start, max_num)
    
    
    for version in gen_range(min_ver, max_ver, max_num):
        print(version)
    

    一些比较:

    使用**

    C:\Work>python -mtimeit -s"import tuples2" "tuples2.version_range((1,1,1),(1,3,5));"
    

    10000 次循环,3 次中的最佳:101 每个循环使用秒

    使用increase

    C:\Work>python -mtimeit -s"import tuples" "tuples.gen_range([1,1,1], [1,3,5], 5)"
    

    1000000 次循环,3 次中的最佳:0.606 每个循环使用秒

    【讨论】:

      猜你喜欢
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      相关资源
      最近更新 更多