255

I'm trying to make a list with numbers 1-1000 in it. Obviously this would be annoying to write/read, so I'm attempting to make a list with a range in it. In Python 2 it seems that:

some_list = range(1,1000)

would have worked, but in Python 3 the range is similar to the xrange of Python 2?

Can anyone provide some insight into this?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
Boathouse
  • 2,665
  • 2
  • 14
  • 6
  • 1
    also, `some_list[i] == i+1`, so you probably don't really need a list anyway. – njzk2 Jun 06 '14 at 15:45
  • 1
    @RikPoggi. for example, one might need to supply a list for a plotting function. Sometimes a range will suffice, but a range cannot be concatenated (is immutable), so if you need to add a default starting value to all lists being plotted, that on needs to be turned into a list also. – SherylHohman Apr 14 '17 at 13:40
  • Essentially any reasonable approach for copying a list, will equally well accept the range as an input and produce the corresponding list as an output. Well, except for slicing-based approaches, since those will just give another `range`. – Karl Knechtel Jun 03 '23 at 08:52

9 Answers9

331

You can just construct a list from the range object:

my_list = list(range(1, 1001))

This is how you do it with generators in python2.x as well. Typically speaking, you probably don't need a list though since you can come by the value of my_list[i] more efficiently (i + 1), and if you just need to iterate over it, you can just fall back on range.

Also note that on python2.x, xrange is still indexable1. This means that range on python3.x also has the same property2

1print xrange(30)[12] works for python2.x

2The analogous statement to 1 in python3.x is print(range(30)[12]) and that works also.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 2
    I would say "construct" or "build" (or possibly "materialise")- as you're not "converting" (as such) a generator to a list, you're creating a new list object from a data source which happens to be a generator... (but s'pose just splitting hairs and not 100% sure what I favour anyway) – Jon Clements Jul 14 '12 at 06:10
  • 2
    My +1 for "construct" as it is consistent with other OO languages. The `list(arg)` is understood in other languages as calling a constructor of the `list` class. Actually, it is also the Python case. The debates whether the object is filled during the construction (as in the C++ case) or only during the first automatically called method (as in the Python `__init__()` method) cannot change the basic abstract idea. My view is that *the list constructor takes the iterator and fills the list with the returned values*. – pepr Jul 14 '12 at 15:51
  • @pepr -- Yeah, I agree. construct is probably the best word to use. One word of caution. It is not guaranteed that `__init__` is called. (from the documentation of `__new__` { http://docs.python.org/reference/datamodel.html#object.__new__ } ) "If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked." – mgilson Jul 14 '12 at 16:09
  • 3
    Why does it give an error in jupyter notebook and working fine in shell? Error: `'range' object is not callable` – subtleseeker Sep 29 '18 at 15:01
  • How could I add `np.nan` into this list? – xarena Jul 19 '20 at 04:13
  • @subtleseeker: It works fine in a notebook. You probably assigned something to `list` or `range`. – user2357112 Feb 05 '21 at 18:21
55

In Pythons <= 3.4 you can, as others suggested, use list(range(10)) in order to make a list out of a range (In general, any iterable).

Another alternative, introduced in Python 3.5 with its unpacking generalizations, is by using * in a list literal []:

>>> r = range(10)
>>> l = [*r]
>>> print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Though this is equivalent to list(r), it's literal syntax and the fact that no function call is involved does let it execute faster. It's also less characters, if you need to code golf :-)

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • 8
    To be clear, you can still one-line it: `[*range(10)]` works just fine for when you don't need the `range` for any purpose but initializing the `list`. Side-note: My favorite(okay, not really) part of the unpacking generalizations is that empty `set`s now have a literal syntax, `{*()}`, or as I call it, the one-eyed monkey operator. ;-) – ShadowRanger Nov 03 '17 at 00:08
  • 2
    @ShadowRanger that's how I originally thought about writing it. I decided to be a bit more verbose in order to not confuse new Python users :-) – Dimitris Fasarakis Hilliard Nov 03 '17 at 00:12
27

in Python 3.x, the range() function got its own type. so in this case you must use iterator

list(range(1000))

26

The reason why Python3 lacks a function for directly getting a ranged list is because the original Python3 designer was quite novice in Python2. He only considered the use of range() function in a for loop, thus, the list should never need to be expanded. In fact, very often we do need to use the range() function to produce a list and pass into a function.

Therefore, in this case, Python3 is less convenient as compared to Python2 because:

  • In Python2, we have xrange() and range();
  • In Python3, we have range() and list(range())

Nonetheless, you can still use list expansion in this way:

[*range(N)]
Neuron
  • 5,141
  • 5
  • 38
  • 59
xuancong84
  • 1,412
  • 16
  • 17
  • 11
    The whole *point* is to make it less convenient to make a `list`, because that's usually the wrong thing to do. For 99 out of 100 use cases, making an actual `list` is inefficient and pointless, since `range` itself acts like an immutable sequence in almost every way, sometimes more efficiently to boot (e.g. containment tests for `int`s are `O(1)`, vs. `O(n)` for `list`s). In Python 2, people tended to use `range` by default, even though `xrange` was almost always the better option; in Python 3, you can to explicitly opt in to the `list`, not get it by accident by using the wrong name. – ShadowRanger Jun 19 '19 at 10:50
  • 21
    The comment about the Python 3 designer and his expertise in Python 2 is quite bold and impertinent. – kazarey Aug 29 '19 at 00:41
  • @kazarey But is it true? There are a lot of things in python that are questionable along these lines – WestCoastProjects Feb 26 '20 at 00:29
  • Wasn't Guido the designer of python3? I cannot find anything to the contrary. – David Waterworth Mar 31 '23 at 00:22
20

You really shouldn't need to use the numbers 1-1000 in a list. But if for some reason you really do need these numbers, then you could do:

[i for i in range(1, 1001)]

List Comprehension in a nutshell:

The above list comprehension translates to:

nums = []
for i in range(1, 1001):
    nums.append(i)

This is just the list comprehension syntax, though from 2.x. I know that this will work in python 3, but am not sure if there is an upgraded syntax as well

Range starts inclusive of the first parameter; but ends Up To, Not Including the second Parameter (when supplied 2 parameters; if the first parameter is left off, it'll start at '0')

range(start, end+1)
[start, start+1, .., end]
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • 24
    Why comprehension? Just: `list(range(1000))` – Rik Poggi Jul 14 '12 at 00:48
  • Thanks! Would you mind explaining why it's i for i in... instead of simply for i in? – Boathouse Jul 14 '12 at 00:50
  • I haven't worked with python3. So I'm not fully certain about how it works. I know comprehensions will work, but wasn't 100% on the casting. But if casting works, then you're right and your way is more pythonic. – inspectorG4dget Jul 14 '12 at 00:51
  • 1
    @inspectorG4dget: It's not "casting", it's calling the [`list()` constructor with an iterable](http://docs.python.org/library/functions.html#list). The `list()` constructor knows how to create a new list when given any iterable object. – Greg Hewgill Jul 14 '12 at 00:53
  • The way list comprehensions usually work is: [doSomethingWith(i) for i in someList], because if you aren't doing something with i (such as taking one of its fields, as in [i.someField for i in someList], or using a method), doing a list comprehension is redundant. Therefore, the syntax for list comprehensions is as you see. – algorowara Jul 14 '12 at 00:54
  • 4
    @inspectorG4dget: `list(range(1000))` will work in python3 just like `list(xrange(1000))` in python2 – Rik Poggi Jul 14 '12 at 00:55
  • range(1000) will return values [0, 1, 2, .. 999] . OP needs range(1,1001) to get a list of [1, 2, 3, .. 1000]. Updating post to reflect this. – SherylHohman Apr 14 '17 at 12:03
  • list comprehension is more generalizable – Zach Boyd Oct 18 '18 at 19:03
13

Python 3:

my_list = [*range(1001)]
Elletlar
  • 3,136
  • 7
  • 32
  • 38
karmasan
  • 157
  • 1
  • 10
4

Actually, if you want 1-1000 (inclusive), use the range(...) function with parameters 1 and 1001: range(1, 1001), because the range(start, end) function goes from start to (end-1), inclusive.

Tshilidzi Mudau
  • 7,373
  • 6
  • 36
  • 49
algorowara
  • 1,700
  • 1
  • 15
  • 15
0

Use Range in Python 3.

Here is a example function that return in between numbers from two numbers

def get_between_numbers(a, b):
    """
    This function will return in between numbers from two numbers.
    :param a:
    :param b:
    :return:
    """
    x = []
    if b < a:
        x.extend(range(b, a))
        x.append(a)
    else:
        x.extend(range(a, b))
        x.append(b)

    return x

Result

print(get_between_numbers(5, 9))
print(get_between_numbers(9, 5))

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]
Rajiv Sharma
  • 6,746
  • 1
  • 52
  • 54
-4

In fact, this is a retro-gradation of Python3 as compared to Python2. Certainly, Python2 which uses range() and xrange() is more convenient than Python3 which uses list(range()) and range() respectively. The reason is because the original designer of Python3 is not very experienced, they only considered the use of the range function by many beginners to iterate over a large number of elements where it is both memory and CPU inefficient; but they neglected the use of the range function to produce a number list. Now, it is too late for them to change back already.

If I was to be the designer of Python3, I will:

  1. use irange to return a sequence iterator
  2. use lrange to return a sequence list
  3. use range to return either a sequence iterator (if the number of elements is large, e.g., range(9999999) or a sequence list (if the number of elements is small, e.g., range(10))

That should be optimal.

xuancong84
  • 1,412
  • 16
  • 17