4

The following variables seem to be similar but they aren't and I don't understand why:

import ujson
import numpy as np

arr = np.array([1, 2, 3, 4])
arr_1 = arr.tolist()
arr_2 = list(arr)

arr_1 == arr_2  # True

ujson.dumps({'arr': arr_1})  # it works
ujson.dumps({'arr': arr_2})  # it does not work (OverflowError: Maximum recursion level reached)

I am using Python-3.5.6, ujson-1.35 and numpy-1.16.4.

Thank you a lot for your help!!

Pablo S.
  • 41
  • 4
  • 1
    It is the same for 1 D array but for higher dimension the .toList is applied recursively, whereas list wont - refer https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.tolist.html – Luv May 04 '20 at 16:11
  • 3
    `tolist` converts it all the way. `list()` just iterates on the first dimension. In this case `arr_2` is a list of `np.int` objects, where as `arr_1` is a list of python integers. – hpaulj May 04 '20 at 16:11
  • Your responses make sense, but how do they explain the observed behaviour in this case? – mapf May 04 '20 at 16:26
  • But, in the end, arr_1 == arr_2 so I understand that both variables should have the same behaviour – Pablo S. May 04 '20 at 16:32
  • Not sure why `ujson` has a recursion error. Perhaps it tries to represent the `int32` number as a dictionary-like object and fails. If you use the standard `json` library you will see that the problem is that it does not know how to serialize numbers stored in the `numpy` `int32` type. See [this question](https://stackoverflow.com/questions/26646362/numpy-array-is-not-json-serializable) – Stuart May 04 '20 at 16:39
  • Yes, I agree with @hpaulj. It fails due to the data type. Anyway, it is a bit confusing. Thank you a lot! – Pablo S. May 04 '20 at 16:48

1 Answers1

4

numpy has its own numeric data types for different levels of precision.

These are created in ways that allow easy comparison with regular Python integers.

np.int32(3) == 3   # True
[np.int32(1), 4] == [1, np.int32(4)]    # True

(Lists are equal in Python if all elements at the same index are equal)

That is why your arr_1 == arr_2.

They cannot readily be serialized to json, but the tolist method converts them to regular Python numeric types which do allow serialization.

Stuart
  • 9,597
  • 1
  • 21
  • 30