13

I'm wondering if there's a more clever way to create a default dict from collections. The dict should have an empty numpy ndarray as default value.

My best result is so far:

import collections
d = collections.defaultdict(lambda: numpy.ndarray(0))

However, i'm wondering if there's a possibility to skip the lambda term and create the dict in a more direct way. Like:

d = collections.defaultdict(numpy.ndarray(0))  # <- Nice and short - but not callable
zinjaai
  • 2,345
  • 1
  • 17
  • 29
  • 3
    Why do you want to use ndarray with defaultdict? You'll have to create a new array each time to insert an item to an existing key, better use list which supports append operation. – Ashwini Chaudhary Jul 29 '14 at 11:38
  • `np.concat()` can be used to accumulate arrays. If the arrays are large and few, this may be more efficient. So, I like the proposed solution above. – Hephaestus Jun 06 '18 at 05:39
  • Accumulation: `base = defaultdict(lambda : np.ndarray(0)); base = np.concatenate((base, new_array)` – Hephaestus Jun 06 '18 at 06:03

2 Answers2

23

You can use functools.partial() instead of a lambda:

from collections import defaultdict
from functools import partial

defaultdict(partial(numpy.ndarray, 0))

You always need a callable for defaultdict(), and numpy.ndarray() always needs at least one argument, so you cannot just pass in numpy.ndarray here.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I'm new to Numpy. Is Ashwini correct when he says 'You'll have to create a new array each time to insert an item to an existing key. Better use list which supports append operation'? – ballade4op52 Jan 26 '17 at 22:57
  • 2
    @Phillip yes, they are correct. Numpy arrays have a fixed size; see [How to extend an array in-place in Numpy?](http://stackoverflow.com/q/13215525). – Martijn Pieters Jan 26 '17 at 23:59
2

Another way is the following if you know the array size beforehand:

new_dict = defaultdict(lambda: numpy.zeros(array_size))
smttsp
  • 4,011
  • 3
  • 33
  • 62