crysis405
crysis405

Reputation: 1131

Generate inverse sequence

I have a sequence

range(0,50,3)

[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

This is the sequence I want to generate (excluding the 3rd element each time), but being able to start and end at nth number:

[1, 2, 4, 5, 7, 8, ...]

Upvotes: 0

Views: 244

Answers (6)

user44484
user44484

Reputation:

For questions like these, where someone is asking "How can I slightly modify the behaviour of a Python built-in function to do X?" I would suggest looking at the PyPy implementation of said function and then just modify it.

In this case, here are PyPy's range() and xrange() implementations.

I realize it's not the easy way out, but you might learn something new in the process.

Basically it looks like what you want is a variant of range() that returns the values which are usually skipped (i.e., the complement of range()). Using range()'s implementation as a starting point, it doesn't look like it would take much work.

Upvotes: 0

georg
georg

Reputation: 214949

How about

r = range(0,50)
del r[::3]
print r
# [1, 2, 4, 5, 7, 8, ...]

Upvotes: 1

Jbeuh
Jbeuh

Reputation: 395

For this particular case :

[x for x in range(50) if x % 3]

Upvotes: 2

Kevin
Kevin

Reputation: 56059

Not the most efficient solution, but quick and easy to understand

excludes = range(0,50,3)
others = [x for x in range(50) if x not in excludes]

Upvotes: 1

mhlester
mhlester

Reputation: 23221

Build a set of the numbers you want to exclude, and test for that in a list comprehension for the full range:

>>> checkset = set(range(0, 50, 3))
>>> [x for x in range(50) if x not in checkset]
[1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49]

Converting the list to a set is not critical, but makes for faster lookup when all you're doing is comparing

Upvotes: 2

NPE
NPE

Reputation: 500317

How about this:

def inv_range(start, stop, step):
  for val in range(start, stop):
    if (val - start) % step != 0:
      yield val

print list(inv_range(0,50,3))

This prints

[1, 2, 4, 5, 7, 8, 10, 11, ...

P.S. If you're using Python 2, replace range() with xrange() to get a constant-memory solution.

Upvotes: 3

Related Questions