Rakesh Adhikesavan
Rakesh Adhikesavan

Reputation: 12826

How do I generate the following series of numbers in Python using List Comprehension?

I am trying to learn List Comprehension, given two numbers as input, I want to generate a series of consecutive numbers.

For example:

Input:  11,16 
Output: [(11,12),(11,12,13),(11,12,13,14),(11,12,13,14,15),(11,12,13,14,15,16)]

So I am trying something like the following:

def genSeries(start,stop):
    return [(start, x) for y in range(start,stop) for x in ?]

Upvotes: 1

Views: 89

Answers (3)

Dilettant
Dilettant

Reputation: 3335

Try this (wow so many people typing simultaneously :-) I suggest simply add 2 once ...:

#! /usr/bin/env python
from __future__ import print_function

def gen_series(start, stop):
    return [tuple(range(start, x + 2)) for x in range(start, stop)]

print(gen_series(11, 16))

yields:

[(11, 12), (11, 12, 13), (11, 12, 13, 14), (11, 12, 13, 14, 15), (11, 12, 13, 14, 15, 16)]

Update: Here is a generator function, so in python v3 one has lazy evaluation ... in python v2 the range might need replacement by xrange to achieve full leisure ;-)

#! /usr/bin/env python
from __future__ import print_function


def series_gen(start, stop):
    """Generator function solution, where the caller can call list on."""
    for x in range(start, stop):
        yield tuple(range(start, x + 2))


print(list(series_gen(11, 16)))

yields (surprise, surprise):

[(11, 12), (11, 12, 13), (11, 12, 13, 14), (11, 12, 13, 14, 15), (11, 12, 13, 14, 15, 16)]

Also as @MartijnPieters kindly notes: One could also just write for the function:

def gen_series(start, stop):
    return ((range(start, x + 2)) for x in range(start, stop))

But take care about the outer parenthesis "being" a generator expression, the "inner" being short for a tuple (trusting it will receive more than one entry.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121744

You need an loop over the stop value; that way you can produces a series of ranges, from range(11, 13) through to range(11, 17):

def genSeries(start, stop):
    return [tuple(range(start, endvalue)) for endvalue in range(start + 2, stop + 2)]

Note that the end value is not included in a range(), so to produce the values from 11 through to 16 inclusive, you need to tell range() to use 17 as the end value. This is also why the endvalue range loops from start + 2 through to stop + 2; the first range is produced from 11 to 12 inclusive, so you need to start at start + 2 to get the exclusive stop value, and the last range goes from start to stop inclusive, so you need to use range(start, stop + 1) to produce that, and that in turn means the endvalue range must go to stop + 2.

Just convert the range() object for each separate endvalue directly to a tuple.

Demo:

>>> genSeries(11, 16)
[(11, 12), (11, 12, 13), (11, 12, 13, 14), (11, 12, 13, 14, 15), (11, 12, 13, 14, 15, 16)]

Upvotes: 2

miindlek
miindlek

Reputation: 3553

[tuple(range(start, i+1)) for i in range(start+1, stop+1)]

Upvotes: 5

Related Questions