I am wondering why the results of these two pieces of code are different,and want to know how to use only for loop to achieve the same result as list comprehension:
a = []
c = []
n = np.array([1,2],dtype=np.float32)
m = np.array([1,3],dtype=np.float32)
b = np.array([3], dtype=np.float32)
a.append([n, m, b])
a.append([n, m, b])
a.append([n, m, b])
e = np.array([])
for obs,_,act in a:
g = [obs,act]
e = np.concatenate([e,g])
e = np.array([e])
f = np.array( [np.concatenate([obs,act]) for obs,_,act in a ])
print("using for loop:\n", e)
print("using list comprehension:\n", f)
The result is:
using for loop:
[[array([1., 2.], dtype=float32) array([3.], dtype=float32)
array([1., 2.], dtype=float32) array([3.], dtype=float32)
array([1., 2.], dtype=float32) array([3.], dtype=float32)]]
using list comprehension:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
why?and how to make the for loop to have the same result as list comprehension?
CodePudding user response:
It is because you are not using the same operation. Try this:
a = []
c = []
n = np.array([1,2],dtype=np.float32)
m = np.array([1,3],dtype=np.float32)
b = np.array([3], dtype=np.float32)
a.append([n, m, b])
a.append([n, m, b])
a.append([n, m, b])
e = []
for obs,_,act in a:
g = [obs,act]
e.append(np.concatenate(g))
e = np.array(e)
f = np.array([np.concatenate([obs,act]) for obs,_,act in a ])
print("using for loop:\n", e)
print("using list comprehension:\n", f)
using for loop:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
using list comprehension:
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
CodePudding user response:
Your a
In [238]: a
Out[238]:
[[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)],
[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)],
[array([1., 2.], dtype=float32),
array([1., 3.], dtype=float32),
array([3.], dtype=float32)]]
One g
:
In [239]: obs,_,act = a[0]
In [240]: g = [obs,act]
In [241]: g
Out[241]: [array([1., 2.], dtype=float32), array([3.], dtype=float32)]
The comprehension uses:
In [243]: np.concatenate(g)
Out[243]: array([1., 2., 3.], dtype=float32)
The iteration does (in the first loop):
In [247]: e = np.array([])
In [248]: np.concatenate([e,g])
<__array_function__ internals>:5: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
Out[248]:
array([array([1., 2.], dtype=float32), array([3.], dtype=float32)],
dtype=object)
That's not joining the same things. To get the same thing, you need to first apply concatenate to g
itself:
In [251]: np.concatenate([e,np.concatenate(g)])
Out[251]: array([1., 2., 3.])
That said, we generally discourage using e=np.concatenate((e,...))
in a loop. List append is faster.