3

I often do the following:

import numpy as np

def my_generator_fun():
    yield x # some magically generated x

A = []
for x in my_generator_fun():
    A += [x]
A = np.array(A)

Is there a better solution to this which operates on a numpy array from the start and avoids the creation of a standard python list?

Note that the += operator allows to extend an empty and dimensionless array with an arbitrarily dimensioned array whereas np.append and np.concatenate demand for equally dimensioned arrays.

morph
  • 305
  • 2
  • 12
  • possible duplicate of http://stackoverflow.com/questions/4535374/initialize-a-numpy-array – John Ruddell Jul 15 '14 at 15:06
  • no, my point is slightly different: image the case where you successively built up the array or you want to initialize each element differently. However, I really need the exactly same functionality, not only the same result. – morph Jul 15 '14 at 15:13
  • why are you even doing a loop with this? why not just make `A = [[0,1],[1,2],[3,4]]` ? – John Ruddell Jul 15 '14 at 15:19
  • another possible duplicate.. you really need to research what you are looking for first... http://stackoverflow.com/questions/10346336/list-of-lists-into-array-in-numpy – John Ruddell Jul 15 '14 at 15:20
  • ok, sorry for the bad example. I will edit it again... – morph Jul 15 '14 at 15:32
  • i just edited my query again.. maybe something like that? not sure what you are getting returned from your function – John Ruddell Jul 15 '14 at 15:44

2 Answers2

4

Use np.fromiter:

def f(n):
    for j in range(n):
        yield j

>>> np.fromiter(f(5), dtype=np.intp)
array([0, 1, 2, 3, 4])

If you know beforehand the number of items the iterator is going to return, you can speed things up using the count keyword argument:

>>> np.fromiter(f(5), dtype=np.intp, count=5)
array([0, 1, 2, 3, 4])
Jaime
  • 65,696
  • 17
  • 124
  • 159
0

To get the same array A, do:

A = numpy.arange(5)

Arrays are not in general meant to be dynamically sized, but you could use numpy.concatenate.

mdurant
  • 27,272
  • 5
  • 45
  • 74