Dictionaries and Default Values

Dictionaries and default values

Like this:

host = connectionDetails.get('host', someDefaultValue)

Is there a way to have a default value inside a dictionary in Python?

You can use a defaultdict.

from collections import defaultdict

colors = defaultdict(lambda: (100, 100, 100))

colors["Black"] = (0, 0, 0),
colors["White"] = (255, 255, 255)

# Prints (0, 0, 0), because "Black" is mapped to (0, 0, 0) in the dictionary.
print(colors["Black"])

# Prints (100, 100, 100), because "Blue" is not a key in the dictionary.
print(colors["Blue"])

How to set default value to all keys of a dict object in python?

You can replace your old dictionary with a defaultdict:

>>> from collections import defaultdict
>>> d = {'foo': 123, 'bar': 456}
>>> d['baz']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'baz'
>>> d = defaultdict(lambda: -1, d)
>>> d['baz']
-1

The "trick" here is that a defaultdict can be initialized with another dict. This means
that you preserve the existing values in your normal dict:

>>> d['foo']
123

How does collections.defaultdict work?

Usually, a Python dictionary throws a KeyError if you try to get an item with a key that is not currently in the dictionary. The defaultdict in contrast will simply create any items that you try to access (provided of course they do not exist yet). To create such a "default" item, it calls the function object that you pass to the constructor (more precisely, it's an arbitrary "callable" object, which includes function and type objects). For the first example, default items are created using int(), which will return the integer object 0. For the second example, default items are created using list(), which returns a new empty list object.

Python Defaultdict with defined dictionary as default value shares the same dictionary between keys

To fix this, you simply need to move your counter_format dictionary construction into the lambda, so that a new counter_format dictionary is created each time you try to access a missing value in your innermost defaultdict

from collections import defaultdict

userDict = defaultdict(lambda:
defaultdict(lambda: {"correct": 0, "incorrect": 0})
)

userDict['a'][1]['correct']+=1
userDict['b'][1]['correct']+=4
userDict['b'][2]['correct']+=1

print(userdict)
defaultdict(<function <lambda> at 0x7f0f6cb38550>,
{'a': defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f0f679424c0>,
{1: {'correct': 1, 'incorrect': 0}}),
'b': defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f0f4caaa430>,
{1: {'correct': 4, 'incorrect': 0},
2: {'correct': 1, 'incorrect': 0}})})

Python dict with default value based on key

I don't think there is a builtin way of doing this. However, instead of subclassing dict and change getitem, you can subclass defaultdict itself to tell __missing__() to call the default_factory with an argument (the key), rather than without args. It is still a custom class, not a builtin, but it should be quite efficient still.

from collections import defaultdict

class DefaultDict(defaultdict):
def __missing__(self, key):
return self.default_factory(key)

Then:

d = DefaultDict(lambda key: key + 5)

d[2]
# 7

How to make a list as the default value for a dictionary?

The best method is to use collections.defaultdict with a list default:

from collections import defaultdict
dct = defaultdict(list)

Then just use:

dct[key].append(some_value)

and the dictionary will create a new list for you if the key is not yet in the mapping. collections.defaultdict is a subclass of dict and otherwise behaves just like a normal dict object.

When using a standard dict, dict.setdefault() correctly sets dct[key] for you to the default, so that version should have worked just fine. You can chain that call with .append():

>>> dct = {}
>>> dct.setdefault('foo', []).append('bar') # returns None!
>>> dct
{'foo': ['bar']}

However, by using dct[key] = dct.get(...).append() you replace the value for dct[key] with the output of .append(), which is None.



Related Topics



Leave a reply



Submit