元组似乎是版本号比较的理想选择(假设只有数字元素,在我的情况下是给定的)。我有两个由整数组成的元组形式的版本号。说那些元组是:
minver = (1,2,3)
maxver = (1,2,9)
是否有一种简单而优雅的方法可以将minver
到maxver
的“范围”作为list
?即对于上述情况,我想得到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,)
,如果(1,0,0)
maxver
包含三个值,则应将其视为tuple
元素(例如(1,2,3)
)。
任何以pythonic方式(优雅)的方式吗?
答案 0 :(得分:6)
好的 - 它是凌晨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)
答案 1 :(得分:1)
为了使事情顺利,这是凌晨3点在这里:)
我认为有可能在没有强大的**
操作的情况下实现这一点,对于大数字而言可能会变得昂贵。
我已经为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 每个循环使用