2

我有一个整数列表:

list = [a,b,c,d]

我想将其转换为这些范围:

0..a
a+1..a+b
a+b+1..a+b+c
a+b+c+1..a+b+c+d

任何想法如何在python中做到这一点?

谢谢

4

3 回答 3

9

一个简单的生成器会做:

def to_ranges(seq):
    iseq = iter(seq)
    x = next(iseq)
    yield range(0,x+1)
    start = x
    for x in iseq:
        stop = start+x
        yield range(start+1,stop+1)
        start = stop


for x in to_ranges([1,2,3,4]):
    print x

这给出了:

[0, 1]         #0 .. a check
[2, 3]         #a+1 (2) .. a+b (1+2=3) check 
[4, 5, 6]      #a+b+1 (1+2+1=4) .. a+b+c (1+2+3=6) check
[7, 8, 9, 10]  #a+b+c+1 (1+2+3+1=7) .. a+b+c+d (1+2+3+4=10) check

终于做对了。不幸的是,第一个循环是特殊的,因为边界条件为 0——所以我们只需要展开那个循环就可以了。

于 2013-02-13T14:25:19.187 回答
0

尽管接受的答案产生了正确的结果,但只能使用几个循环和列表生成器来获得解决方案。更高级的语言运算符似乎不合适,因为问题是在询问这样一个简单的问题——生成一些列表。

此解决方案仅适用于正整数。处理带有负数的序列留给读者作为练习。

# starting data
nums = [3, 5, 22, 6]

# Generate endpoints for output sequences.
# Note that the first sequence starts specially at 0.
endpoints = [0]
for i in range(len(nums)):
    endpoints.append(endpoints[i] + nums[i])
endpoints[0] = -1

# Generate output sequences.
outseqs = []
for i in range(1, len(endpoints)):
    outseq = [n for n in range(endpoints[i - 1] + 1, endpoints[i] + 1)]
    outseqs.append(outseq)

# Display output sequences.
for i in range(len(outseqs)):
    print outseqs[i]
于 2013-02-13T15:33:38.587 回答
0

如果输入中有负数,那么到目前为止提供的所有解决方案都不起作用,因此需要反向顺序的范围。我的解决方案涵盖了这一点。适用于 Python 2 和 3。这里是:

from itertools import izip

# create the x (=start) and y (=stop) coordinates for the ranges separately
def _get_xs(iterable):
    yield 0
    for i in xrange(1, len(iterable)):
        yield sum(iterable[:i]) + 1

def _get_ys(iterable):
    yield iterable[0]
    for i in xrange(1, len(iterable)):
        yield sum(iterable[:i+1])

def to_ranges(iterable):
    xs = _get_xs(iterable)
    ys = _get_ys(iterable)
    for x, y in izip(xs, ys):
        if x < y:
            step = 1
            y += 1
        elif x > y:
            step = -1
            y -= 1
        else:
            step = 0
        try:
            yield range(x, y, step)
        except ValueError:
            yield [x]

例子:

# edge case: instead of malformed ranges such as range(10, 10), put [10] instead

>>> list(to_ranges([1, 2, 3, 4]))
[[0, 1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]

>>> list(to_ranges([4, 3, 2, 1]))
[[0, 1, 2, 3, 4], [5, 6, 7], [8, 9], [10]]

>>> list(to_ranges([4, 3, 2, -1]))
[[0, 1, 2, 3, 4], [5, 6, 7], [8, 9], [10, 9, 8]]

>>> list(to_ranges([-4, -3, -2, -1]))
[[0, -1, -2, -3, -4], [-3, -4, -5, -6, -7], [-6, -7, -8, -9], [-8, -9, -10]]

>>> list(to_ranges([-1, -2, -3, -4]))
[[0, -1], [0, -1, -2, -3], [-2, -3, -4, -5, -6], [-5, -6, -7, -8, -9, -10]]
于 2013-02-13T16:47:25.970 回答