How to Enumerate a Range of Numbers Starting at 1

How to enumerate a range of numbers starting at 1

As you already mentioned, this is straightforward to do in Python 2.6 or newer:

enumerate(range(2000, 2005), 1)

Python 2.5 and older do not support the start parameter so instead you could create two range objects and zip them:

r = xrange(2000, 2005)
r2 = xrange(1, len(r) + 1)
h = zip(r2, r)
print h

Result:


[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

If you want to create a generator instead of a list then you can use izip instead.

Python -- how to force enumerate to start at 1 -- or workaround?

Since Python 2.6, enumerate() takes an optional start parameter to indicate where to start the enumeration. See the documentation for enumerate.

How to iterate the range of numbers in a list?

You are already fetching value from mylist in the first for loop. After than in the range you can just put that value directly (ie in second for loop) as shown below.

mylist = [100, 500, 1000]

for i in mylist:
for j in range(0, i):
print(j)

Python enumerate list setting start index but without increasing end count

It sounds as if you want to slice the list instead; still start enumerate() at one to get the same indices:

for i, item in enumerate(valueList[1:], start=1):

This then loops over valueList starting at the second element, with matching indices:

>>> valueList = [1, 2, 3, 4]
>>> secondList = ['a', 'b', 'c', 'd']
>>> for i, item in enumerate(valueList[1:], start=1):
... print(secondList[i])
...
b
c
d

In this case, I'd just use zip() instead, perhaps combined with itertools.islice():

from itertools import islice

for value, second in islice(zip(valueList, secondList), 1, None):
print(value, second)

The islice() call skips the first element for you:

>>> from itertools import islice
>>> for value, second in islice(zip(valueList, secondList), 1, None):
... print(value, second)
...
2 b
3 c
4 d

Pythonic way to iterate through a range starting at 1

range(1, n+1) is not considered duplication, but I can see that this might become a hassle if you were going to change 1 to another number.

This removes the duplication using a generator:

for _ in (number+1 for number in range(5)):
print(_)

Why does range(start, end) not include end?

Because it's more common to call range(0, 10) which returns [0,1,2,3,4,5,6,7,8,9] which contains 10 elements which equals len(range(0, 10)). Remember that programmers prefer 0-based indexing.

Also, consider the following common code snippet:

for i in range(len(li)):
pass

Could you see that if range() went up to exactly len(li) that this would be problematic? The programmer would need to explicitly subtract 1. This also follows the common trend of programmers preferring for(int i = 0; i < 10; i++) over for(int i = 0; i <= 9; i++).

If you are calling range with a start of 1 frequently, you might want to define your own function:

>>> def range1(start, end):
... return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

How to find out if a number is in a list of ranges?

Simply iterate over the list, take both values and create a range from those values and check if b in range(...), also use enumerate, start it from 1 and you will get in which consecutive range in the list the number is.

a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
b = 167772241

for index, (start, end) in enumerate(a, start=1):
if b in range(start, end + 1):
print(index)
break

You can also use a list comprehension:

a = [[167772352, 167772415], [167772160, 167772223], [167772288, 167772351], [167772224, 167772255]]
b = 167772241

index = [b in range(start, end + 1) for start, end in a].index(True) + 1
print(index)

Also note the end + 1 used in both ranges, that is because the range doesn't include its end value so adding 1 means that the range is inclusive on both sides. Also both methods will get the index that starts from one, which is how you would usually count (1, 2, 3, 4, ...) as you have stated in your question that b should be in the fourth range (which means that you started counting from 1)

How do I create a list with numbers between two values?

Use range. In Python 2, it returns a list directly:

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

In Python 3, range is an iterator. To convert it to a list:

>>> list(range(11, 17))
[11, 12, 13, 14, 15, 16]

Note: The second number in range(start, stop) is exclusive. So, stop = 16+1 = 17.


To increment by steps of 0.5, consider using numpy's arange() and .tolist():

>>> import numpy as np
>>> np.arange(11, 17, 0.5).tolist()

[11.0, 11.5, 12.0, 12.5, 13.0, 13.5,
14.0, 14.5, 15.0, 15.5, 16.0, 16.5]

See: How do I use a decimal step value for range()?

range(len(list)) or enumerate(list)?

Some quick timing runs seem to give the 2nd option using range() a slight edge over enumerate():

timeit a = [f(n) for n, _ in enumerate(mlist)]
10000 loops, best of 3: 118 us per loop

timeit a = [f(n) for n in range(len(mlist))]
10000 loops, best of 3: 102 us per loop

and just for fun using xrange() (Python v2.7.2)

timeit a = [f(n) for n in xrange(len(mlist))]
10000 loops, best of 3: 99 us per loop

I would favor readable code first, then using xrange() if available (i.e., Pre-Python v 3.x), followed by range() and enumerate().



Related Topics



Leave a reply



Submit