2013-02-13 5 views
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?

Благодаря

+0

являются те диапазоны вы на самом деле хотите? – mgilson

+0

помните, что вы, вероятно, не хотите называть свой список «списком» со своего встроенного объекта python. – Hoopdady

+0

@Hoopdady Да, спасибо за это ... Я назвал его для уточнения. – bioinf80

ответ

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, поэтому нам просто нужно развернуть это, и все правильно с миром.

+0

Я не закончил свой утренний кофе, но это, похоже, не дает результатов, которые запрашивает OP. – DSM

+0

@ DSM - Да. См. Мое редактирование. – mgilson

+0

+1, но все еще один +1 отсутствует '(a * + 1 * ... a + b)'? – root

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] 
+0

В качестве входного сигнала, например, ваш код дает [[0], [1, 2], [3, 4, 5], [6, 7, 8, 9 ]] '.Вместо этого он должен быть '[[0, 1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]' – pemistahl

+0

@PeterStahl Исправлено. –

+0

Да, теперь это работает. Однако ваше решение также страдает из-за того, что он не работает для отрицательных чисел на входе. – pemistahl

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]] 
Смежные вопросы