2

I want a dictionary with default to None. I have two ways to implement: 1) use collections.defaultdict and set default value to None. https://docs.python.org/2/library/collections.html

2) use an ordinary dictionary but use .get() to get the value. When the key does not exist, by default it returns None.

Which way is better?

Lisa
  • 4,126
  • 12
  • 42
  • 71
  • Try this thread: https://stackoverflow.com/questions/7423428/python-dict-get-vs-setdefault – alfonso May 11 '18 at 02:34
  • 3
    As usual, the answer to "which is better?" is "that depends". These approaches have tradeoffs. What do you need it for? – gilch May 11 '18 at 02:37

2 Answers2

5

defaultdict will use more memory than dict.get() since if no key found, defaultdict will set the default value in wrapped dict with the key.

on the other hand, dict.get() just return the default value directly if no key found in dict. No extra space needed.

Running 0.2 billion with empty dict using python2,

200000000  199.584    0.000  283.804    0.000 default.py:11(get_default)
200000000  158.268    0.000  158.268    0.000 default.py:14(get_defaultdict)

The memory usage when running 1 million data with empty dict using python2,

Line #    Mem usage    Increment   Line Contents
================================================
17   10.918 MiB   10.918 MiB   @profile
18                             def run_get_default():
19   10.918 MiB    0.000 MiB       h = {}
20   10.918 MiB    0.000 MiB       for i in xrange(0, COUNT):
21   10.918 MiB    0.000 MiB           get_default(h, i)
22   10.918 MiB    0.000 MiB           get_default(h, i)

Line #    Mem usage    Increment   Line Contents
================================================
24   10.918 MiB   10.918 MiB   @profile
25                             def run_get_defaultdict():
26   10.918 MiB    0.000 MiB       h = defaultdict(int)
27   83.496 MiB    7.273 MiB       for i in xrange(0, COUNT):
28   83.496 MiB   58.141 MiB           get_defaultdict(h, i)
29   83.496 MiB    7.164 MiB           get_defaultdict(h, i)

defaultdict needs a callable value as the dict default value, you can also use the function or lambda to customize your own default value per requirement

dict.get($key, $default) is easier to get the default per record

Thanks

qingdaojunzuo
  • 416
  • 1
  • 3
  • 13
2

If you just want the default value to be None. It doesn't get simpler then just using the .get() method.

Alternatively, if you want the value to subsequently be set to None after, you could use the setdefault method

a = {}
a[1] = "1"

print(a.get(1)) # prints 1
print(a.get(2)) # prints None
print(a.setdefault(2, None)) # prints None, and now a has an entry with key 2, and a value of None

To use the defaultdict, you would write something like this

from collections import defaultdict
b = defaultdict(lambda: None) # this lambda returns the default value, 
# None in this case

b[1] = "1"
print(b[1]) # prints 1
print(b[2]) # prints None

As qingdaojunzuo has pointed out in his answer, .get() is faster then using a default dictionary. So it is probably best to stick with that. However, if you need to return something other then None, defaultdict is the answer

user1762507
  • 772
  • 9
  • 32