Reputation: 145
I was working with a numpy
array called predictions
. I was playing around with the following code:
print type(predictions)
print list(predictions)
The output was:
<type 'numpy.ndarray'>`
[u'yes', u'no', u'yes', u'yes', u'yes']
I was wondering how numpy
managed to build their ndarray
class so that it could be converted to a list not with their own list
function, but with the standard Python function.
Python version: 2.7, Numpy version: 1.9.2
Upvotes: 2
Views: 2974
Reputation: 231385
As others have written, list()
works because an array is an iterable. It is equivalent to [i for i in arr]
. To understand it you need to understand how iteration over an array works. In particular, list(arr)
is not the same as arr.tolist()
.
In [685]: arr=np.array('one two three four'.split())
In [686]: arr
Out[686]:
array(['one', 'two', 'three', 'four'],
dtype='<U5')
In [687]: ll=list(arr)
In [688]: ll
Out[688]: ['one', 'two', 'three', 'four']
In [689]: type(ll[0])
Out[689]: numpy.str_
In [690]: ll1=arr.tolist()
In [691]: ll1
Out[691]: ['one', 'two', 'three', 'four']
In [692]: type(ll1[0])
Out[692]: str
The print display of ll
and ll1
looks the same, but the type
of the elements is different, one is a str
, the other a str
wrapped in a numpy
class. That distinction has come up in a recent question about serializing an array.
The distinction becomes more obvious when arr
is 2d. Simple interation then produces the rows, not the elements:
In [693]: arr=np.reshape(arr,(2,2))
In [694]: arr
Out[694]:
array([['one', 'two'],
['three', 'four']],
dtype='<U5')
In [695]: list(arr)
Out[695]:
[array(['one', 'two'],
dtype='<U5'), array(['three', 'four'],
dtype='<U5')]
In [696]: arr.tolist()
Out[696]: [['one', 'two'], ['three', 'four']]
list(arr)
is now two arrays, while arr.tolist()
is a nested list.
Python Pandas: use native types
Why does json.dumps(list(np.arange(5))) fail while json.dumps(np.arange(5).tolist()) works
Upvotes: 2
Reputation: 122052
I have answered from the pure Python perspective below, but
numpy
's arrays are actually implemented in C - see e.g. thearray_iter
function.
The documentation defines the argument to list
as an iterable
; new_list = list(something)
works a little bit like:
new_list = []
for element in something:
new_list.append(element)
(or, in a list comprehension: new_list = [element for element in something]
). Therefore to implement this behaviour for a custom class, you need to define the __iter__
magic method:
>>> class Demo(object):
def __iter__(self):
return iter((1, 2, 3))
>>> list(Demo())
[1, 2, 3]
Note that conversion to other types will require different methods.
Upvotes: 2