Python Forum

Full Version: Help me understand a simple list comprehension
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi All,

I'm a Python newbie, so this is probably a very simple (perhaps stupid) question that I'm asking...but for the life of me, I cannot understand how the code below works...to give the output it does:

Okay, just to clarify though...that code pertains to NumPy...so not really a straight Python question per se.

import numpy as np
np.array([range(i, i + 3) for i in [2, 4, 6]])
The result from the above is as follows:

[[2, 3, 4],
[4, 5, 6],
[6, 7, 8]]

If someone could please help me understand what is going on (within the "np.array()" portion), which produces the numbers in the 3D array, that would be super helpful Smile

I specifically cannot understand what the first part does i.e. "range(i, i + 3)"...and how it has any bearing on/relation to the second part i.e. "for i in [2, 4, 6]"

I might as well throw in another question: Can something like this (3D array) be achieved in straight-up Python as well? If yes, how?

Thanks.
Ah, yes, list comprehensions. They're a trip when you first learn about them.

The portion you're referencing is equivalent to:

out = []
for i in [2, 4, 6]:
    out.append(list(range(i, i + 3)))
It will loop over the list [2, 4, 6] assigning the variable "i" to the value of the current iteration each time. So, the first time through, i = 2; the second time, i = 4; etc.

The range() function returns an iterator starting at the first value provided and incrementing to the second value. So, range(i, i + 3) will start at "i" and end at "i + 3". For the first iteration of the loop, i = 2 and the call will be for range(2, 5), which can be used to produce the list [2, 3, 4].

In short, the first part of the list comprehension instructs the interpreter what to add to the list while the second part provides a loop expression to direct the process. Each time the loop iterates, it appends a new range() to the list. However, list comprehensions are faster than the equivalent code I wrote above.

To accomplish this without numpy:

[list(range(i, i + 3)) for i in [2, 4, 6]]
Wow!!! Thanks Stullis!

Yours is such an amazing answer, that I don't even need any further clarification! Very well explained, and certainly very easy to understand!

So, just out of curiosity (and I think I might already know the answer): does it matter (or make a difference) that when this is accomplished with plain Python, the result (which is essentially a list of lists) is displayed as a one-liner...whereas, when using numpy, the result is displayed in three lines i.e. rows and columns (which visually makes it look like a true 3D array)...or is it generally just optics, and more specifically, just the way the ".array()" function of numpy has been coded to display the result vs how Python has been coded to display the result?
(Oct-17-2018, 11:33 AM)PiPy Wrote: [ -> ]which visually makes it look like a true 3D array

Actually it's 2D array. What you see/understand as mere visual difference in in fact much more than that. np.array() will produce ndarray object, i.e. you will have access to all the properties and methods provided for that class. In other words it will take the list of lists and transform it in another type of object.

Lists are container type too. Lists of lists resemble 2D "arrays" but they have their own properties and methods. Also unlike ndarrays they can hold different types and also be of different size.
Thanks buran, for the additional information you provided...very helpful (and interesting to learn) indeed!

Your explanation brings up another question/clarification though i.e. when would I use one, over the other i.e. numpy ndarray object vs python list object?

Thanks also for clarifying re. the 2D array. I realize that there is no depth (3rd dimension) involved.
(Oct-17-2018, 02:06 PM)PiPy Wrote: [ -> ]Your explanation brings up another question/clarification though i.e. when would I use one, over the other i.e. numpy ndarray object vs python list object?

I believe you may find this answer helpful. numpy is (as the name implies) for calculations and matrix processing. You can keep only uniform data in numpy array.

list is a general-purpose flexible sequence container, that can hold objects of any type - including another list. list is one-dimesional - even if it is a list of lists, you cannot slice it by columns.

You can change list length - you cannot change array shape (you may create a new array with a different shape from an existing one)

numpy is not a part of a standard Python installation, so - if you are not sure when to use numpy, you probably can manage with lists.
Thanks volcano63...for answering my question..and also for providing me a the link, to what looks like gibberish to me, at least at this stage of my learning!