14

in python is there a way to create of list that will skip numbers and will continue after skipping? something like the following code:

x = [1...3, 6...10]
print(x)
# [1,2,3,6,7,8,9,10]

Well its easy to write a for loop and then skip each defined index/value, or i can just use range, what I am looking for is a shorter more readable line. If not I can understand.

yatu
  • 86,083
  • 12
  • 84
  • 139
Led
  • 662
  • 1
  • 19
  • 41
  • 2
    Python doesn't support *any* special range syntax, never mind implicit concatenation of such within the same list literal. – chepner Apr 12 '19 at 22:46

4 Answers4

22

Simplest way to do this is to call range() and unpack result inside list assignment.

x = [*range(1, 4), *range(6, 11)]
Olvin Roght
  • 7,677
  • 2
  • 16
  • 35
  • 4
    While this works, it's worth noting that this creates the entire list in memory. If you just want to iterate over the resulting sequence once, then this will consume more memory than the `itertools.chain` method. 40 bytes per number on my system, to be exact. This is fine for small sequences, but if your sequence has a billion numbers, well, you do the math... – marcelm Apr 12 '19 at 18:35
14

Alternatively you can use itertools.chain:

>>> import itertools
>>> list(itertools.chain(range(1, 5), range(20, 25)))
[1, 2, 3, 4, 20, 21, 22, 23, 24]
Netwave
  • 40,134
  • 6
  • 50
  • 93
8

If numpy is an option, you can use np.r_ to concatenate slice objects:

import numpy as np

np.r_[1:4, 6:11]
# array([ 1,  2,  3,  6,  7,  8,  9, 10])
yatu
  • 86,083
  • 12
  • 84
  • 139
2

You can turn it into a recursive function:

def recursive_ranges(ranges):
    if len(ranges) == 1:
        return list(range(*ranges[0]))
    else:
        return list(range(*ranges[0])) + recursive_ranges(ranges[1:])

You can then call this, specifying ranges as a list of lists:

ranges = [[1, 4], [6, 11]]
recursive_ranges(ranges)
# [1, 2, 3, 6, 7, 8, 9, 10]

Note the *ranges[0] is used to unpack the elements in ranges[0] into individual arguments. Essentially the recursive function keeps grabbing the first element of ranges, each element of which is a two-element array, and passing those numbers into the range() method as two different values instead of one array. That's what the * does, it unpacks the array. First call, you unpack [1, 4] into range(1, 4) and then append the next call of the recursive function to it.

Basically this unpacks into the following:

list(range(1, 4)) + list(range(6, 11))

but you get to use a much more compact syntax, just passing a list of lists.

Engineero
  • 12,340
  • 5
  • 53
  • 75