22

What is the difference between applying list() on a numpy array vs. calling tolist()?

I was checking the types of both outputs and they both show that what I'm getting as a result is a list, however, the outputs don't look exactly the same. Is it because that list() is not a numpy-specific method (i.e. could be applied on any sequence) and tolist() is numpy-specific, and just in this case they are returning the same thing?

Input:

points = numpy.random.random((5,2))
print "Points type: " + str(type(points))

Output:

Points type: <type 'numpy.ndarray'>

Input:

points_list = list(points)
print points_list
print "Points_list type: " + str(type(points_list))

Output:

[array([ 0.15920058, 0.60861985]), array([ 0.77414769, 0.15181626]), array([ 0.99826806, 0.96183059]), array([ 0.61830768, 0.20023207]), array([ 0.28422605, 0.94669097])]
Points_list type: 'type 'list''

Input:

points_list_alt = points.tolist()
print points_list_alt
print "Points_list_alt type: " + str(type(points_list_alt))

Output:

[[0.15920057939342847, 0.6086198537462152], [0.7741476852713319, 0.15181626186774055], [0.9982680580550761, 0.9618305944859845], [0.6183076760274226, 0.20023206937408744], [0.28422604852159594, 0.9466909685812506]]
Points_list_alt type: 'type 'list''
jonrsharpe
123k30 gold badges274 silver badges485 bronze badges
asked Jan 11, 2015 at 18:46
2
  • 5
    One is a list of lists, the other a list of numpy arrays -- because .tolist "walks down the tree" and correctly makes every level into lists, while list(...) just "walks" the top level. So, what is the question...? Commented Jan 11, 2015 at 18:52
  • There is no need for this statement at all: print "Points type: " + str(type(points)), you can check the type of the variable by using type(varName_here) i.e., type(points) Commented Jan 11, 2015 at 18:56

4 Answers 4

27

Your example already shows the difference; consider the following 2D array:

>>> import numpy as np
>>> a = np.arange(4).reshape(2, 2)
>>> a
array([[0, 1],
 [2, 3]])
>>> a.tolist()
[[0, 1], [2, 3]] # nested vanilla lists
>>> list(a)
[array([0, 1]), array([2, 3])] # list of arrays

tolist handles the full conversion to nested vanilla lists (i.e. list of list of int), whereas list just iterates over the first dimension of the array, creating a list of arrays (list of np.array of np.int64). Although both are lists:

>>> type(list(a))
<type 'list'>
>>> type(a.tolist())
<type 'list'>

the elements of each list have a different type:

>>> type(list(a)[0])
<type 'numpy.ndarray'>
>>> type(a.tolist()[0])
<type 'list'>

The other difference, as you note, is that list will work on any iterable, whereas tolist can only be called on objects that specifically implement that method.

answered Jan 11, 2015 at 18:52
2

.tolist() appears to convert all of the values recursively to python primitives (list), whereas list creates a python list from an iterable. Since the numpy array is an array of arrays, list(...) creates a list of arrays

You can think of list as a function that looks like this:

# Not the actually implementation, just for demo purposes
def list(iterable):
 newlist = []
 for obj in iter(iterable):
 newlist.append(obj)
 return newlist
answered Jan 11, 2015 at 18:52
2

The major difference is that tolist recursively converts all data to python standard library types.

For instance:

>>> arr = numpy.arange(2)
>>> [type(item) for item in list(arr)]
[numpy.int64, numpy.int64]
>>> [type(item) for item in arr.tolist()]
[builtins.int, builtins.int]

Aside from the functional differences tolist will generally be quicker as it knows it has a numpy array and access to the backing array. Whereas, list will fall back to using an iterator to add all the elements.

In [2]: arr = numpy.arange(1000)
In [3]: %timeit arr.tolist()
10000 loops, best of 3: 33 μs per loop
In [4]: %timeit list(arr)
10000 loops, best of 3: 80.7 μs per loop

I would expect the tolist to be

answered Jan 11, 2015 at 19:34
0

Additional differences:

  1. If you have a 1D numpy array and convert it to a list by using tolist() that will change numpy scalar to the nearest compatible built-in python type. On the contrary, list() does not, it keeps the type of numpy scalar as it is.
# list(...)
a = np.uint32([1, 2])
a_list = list(a) # [1, 2]
type(a_list[0]) # <class 'numpy.uint32'> 
# .tolist()
a_tolist = a.tolist() # [1, 2]
 
type(a_tolist[0]) # <class 'int'>
  1. If the numpy array with a scalar value meaning 0D array, using list() will throw an error but tolist() will only convert it as python scalar without any errors.
a = np.array(5)
list(a) # TypeError: iteration over a 0-d array
a.tolist() # 5
answered Aug 19, 2021 at 20:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.