Live data from Hacker News

A practical usage of ChainMap in Python

blog.florimondmanca.com

11–16 of 16 posts

Re: A practical usage of ChainMap in Python

#11
post #4

I see the example use case is exactly the same as the one given in the python documentation [1]. Any other practical use cases? [1] https://docs.python.org/3.7/library/collections.html#collect...

It's nice for anything with nested scopes -- Example that came to mind since a link to Crafting Interpreters was also on the front page: Variable lookup for for an interpreter. If each scope gets its own set of bindings, you can make a ChainMap from most specific to least specific and look up values from that instead of manually traversing scopes.

Re: A practical usage of ChainMap in Python

#13
post #2

>>> from collections import ChainMap >>> inv = ChainMap({'Monopoly': 20, 'Nintendo': 200}, {'iMac': 1000, 'Chromebook': 800, 'PC': 400}, {'Jeans': 40, 'T-Shirt': 10}) >>> inv['iMac'] = 9001 >>> inv ChainMap({'Monopoly': 20, 'Nintendo': 200, 'iMac': 9001}, {'iMac': 1000, 'PC': 400, 'Chromebook': 800}, {'T-Shirt': 10, 'Jeans': 40}) This strikes me very much as the wrong default behaviour. If you want the (IMO expected)…

chain_map.maps[0][key] = value I wouldn't expect this to work because `0` is a valid key. It's not safe to assume that an integer lookup is an index.

In his example maps is a list, no?

Re: A practical usage of ChainMap in Python

#14
post #6
post #2

>>> from collections import ChainMap >>> inv = ChainMap({'Monopoly': 20, 'Nintendo': 200}, {'iMac': 1000, 'Chromebook': 800, 'PC': 400}, {'Jeans': 40, 'T-Shirt': 10}) >>> inv['iMac'] = 9001 >>> inv ChainMap({'Monopoly': 20, 'Nintendo': 200, 'iMac': 9001}, {'iMac': 1000, 'PC': 400, 'Chromebook': 800}, {'T-Shirt': 10, 'Jeans': 40}) This strikes me very much as the wrong default behaviour. If you want the (IMO expected)…

hmm. That is not what I would have expected. I would have thought it would update the value of the first map with the key "iMac", otherwise, add the key to the top level. The same would go for: >>> del inv['IMac'] deleting the key in the first mapping it appears. My guess is it is designed to ensure that updating a key will not update accidentally update a default mapping? This behavior could easily be prevented thou…

Seems to be a strict design goal that the nothing below the top-most mapping is changed, which I appreciate.

Re: A practical usage of ChainMap in Python

#15
post #3

Earlier quoted context omitted.

Your point is interesting, and it’s how I’ve designed a lot of APIs when I’m not sure how I’ll end up needing the class or function the most: slightly less ergonomic in the know use case, but across the board it has a higher “median” ergonomicity. A third alternative of course would be to add a method to the constructor, specifying this behavior (e.g. write_depth=1). However, it appears that the “locals, globals, bui…

That design would have made ordered dict incompatible with dict (an ordered dict couldn't be constructed with an ordered key, same for an unordered dict), and at the time, keyword args were unordered, so an ordered dict had to be constructed with an iterable of tuples instead of key value pairs.

I disagree. There’s a strange precedent for builtins overloading like ‘type’. The same could be done for ‘dict’. Do you want me to share a satisficing call signature?

Re: A practical usage of ChainMap in Python

#16
post #15

Earlier quoted context omitted.

That design would have made ordered dict incompatible with dict (an ordered dict couldn't be constructed with an ordered key, same for an unordered dict), and at the time, keyword args were unordered, so an ordered dict had to be constructed with an iterable of tuples instead of key value pairs.

I disagree. There’s a strange precedent for builtins overloading like ‘type’. The same could be done for ‘dict’. Do you want me to share a satisficing call signature?

Type doesn't take in kwargs?

But yes, I'm interested in the call signature you propose such that it's possible to tell whether

    dict(ordered=True)
Means `OrderedDict([])` or `{'ordered': True}`.
Post reply on HN