Home > Back-end >  Create Python alternating range programmatically
Create Python alternating range programmatically

Time:01-16

I am looking for a convenient way to create an ordered, alternating (negative, positive while decrementing and incrementing by one from previous pair) list of integers in the form of

[-1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, 8, -9, 9, -10, 10]

with Python with variable length/end integer, like: alternating_range(2) = [-1, 1, -2, 2]

I can easily do this in a "for loop" but I am looking for a more "Pythonic" way

CodePudding user response:

Here are two possible solutions:

The first one using list comprehension:

def alternating(i : int) -> List[int]:
    return [i * sign for i in range(1, i   1) for sign in [1, -1]]

And the second one using numpy:

import numpy as np
def alternating(i : int) -> np.ndarray:
    return np.c_[(r := np.arange(1, i)), -1 * r].reshape(-1)

CodePudding user response:

You could do it as a generator like this:

def alternating_range(x):
    return (i for j in range(1, x 1) for i in (-j,j))

However, I think the for loop solution is more readable. You cite "flat is better than nested". This solution has only one level of nesting while the one above has 2.

def alternating_range(x):
    for i in range(1, x 1):
        yield -i
        yield i

Both of these return generators, you can use list(alternating_range(x)) to convert to a list.

CodePudding user response:

I believe you want something fancy, if however not very efficient, like this:

def alternating_range(end):
  return list(sum(map(lambda x: (x*-1, x), range(1, end 1)), ()))

print(alternating_range(10))

No imports required, no apparent nesting (for-loop) in your code

CodePudding user response:

Another (quite ugly looking) option, using list comprehension with only one for statement is:

def alternating_range(n):
    return [
        (i   (i % 2) - int((i   1) / 2)) * (-1)**i
        for i in range(1, 2 * n   1)
    ]
  • Related