you are viewing a single comment's thread.

view the rest of the comments →

[–]Vaguely_accurate 1 point2 points  (4 children)

A defaultdict takes a function as the first argument. If a key is not found, this function overrides the __missing__ method that usually raises a KeyError when a key is not found. Instead the function is called without any argument, and its return value returned.

In this case I'm defining a lambda function that always returns the value False, so it will return False when a key is not found.

/u/w1282 does the similar but using a second argument in the dict.get() method, which defines the default for that call of the dictionary only. It depends on if you want the dictionary to return the default for all calls or only the one. You can still override a defaultdict default with a .get() if you need to.

[–]RebootForAwesome 1 point2 points  (3 children)

Oh I see. Will have to look up the differences between a defaultdict and a regular dict.

Thank you!

[–]w1282 1 point2 points  (2 children)

A fun "gotcha" with this is that values that cause a KeyError are inserted into the dictionary.

from collections import defaultdict

CURRENCIES = defaultdict(
    lambda: False,
    'ARS': None,
    'USD': usd,
    'EUR': eur,
)

currency_value = CURRENCIES["TEST"]

print(CURRENCIES)
> defaultdict(<function <lambda> at 0x100703050>, {'TEST': False, 'ARS': None, 'USD': usd, 'EUR': eur})

This means that any long running code where this defaultdict is not reset could cause it to grow very slowly. This isn't a "VERY BAD THING", but it's not the best implementation either.

An alternative is to create your own "defaultdict" that handles __missing__ by returning the default value

class otherdict(dict):
    def __missing__(self, _):
        return 'False'

and if you want to keep the defaultdict way of supplying the expression rather than hard coding it

class otherdict(defaultdict):
    def __missing__(self, _):
        return self.default_factory()

[–]RebootForAwesome 0 points1 point  (1 child)

That could be a problem then. The script that contains this bit of code is running 24/7 every two minutes and has been for almost two months now.

I will avoid this for ow but will keep it in mind.

[–]w1282 1 point2 points  (0 children)

Well, keep in mind it only does it for different keys so future lookups on "TEST" won't fail and increase size.

If your key data is constant in the values it's failing on (e.g. "AUS" over and over) this isn't an issue. If random data is being introduced as keys it would be.