4 ms·
Dictionary lookup is often a handy way to solve small tasks, when (a) there's no need to build a whole class hierarchy, etc. and (b) the solution is nicely decl
by chriswarbo 3y ago
Dictionary lookup is often a handy way to solve small tasks, when (a) there's no need to build a whole class hierarchy, etc. and (b) the solution is nicely declarative/data-oriented.
The article talks about string keys, but Python allows many things to be used as keys. For example, instead of chains of `elif` we can look up `True` in a dictionary:
>>> age = 25
>>> {
... (age < 18): "Forbidden",
... (age == 18): "OK, you're old enough now",
... (age > 18 and age < 20): "LOL teen emoji amirite?",
... (age >= 20 and age < 40): "Hi",
... (age >= 40): "Welcome",
... }[True]
'Hi'
One thing that's annoying with this pattern is that Python calculates values eagerly, so we can't use it for expensive calculations or observable effects. To make the values lazy we can wrap them in `lambda:`, but at that point we're essentially re-implementing dynamic dispatch, so classes may be better (or a couple of `elif`s, at most). Note: that's what the article's doing ;)
- frou_dh 3y agoThat's neat but it's also kinda the definition of "clever code". When a later reader is going to have to pause and ask themselves what on earth is this.
- regularfry 3y agoIt's worse than that because anyone who's touched a Lisp will think "this is a cond system! I know this!" and get the semantics exactly wrong.
- someguy7250 3y agoHonestly when I accepted that clever code is bad code, my passion for coding died and now I just want to coast until I get fired and then go work at a phone repair shop I think when I picked my major, I never understood what software engineering is, or even what engineering is. Honestly I shouldn't be complaining. So many people have it worse. Coding would still be fun if it weren't a job, where we bend tech backwards to please the users (instead of teaching users to do the right thing)
- lacrimacida 3y agoThere are still places you could clever code your way around problems. But production code should still be free of clever code.
- Phemist 3y agoThere is a problem with "overlapping" conditions. If multiple conditions in a elif statement would evaluate to true, then the first of these conditions is chosen. For this dictionary approach, the last occurrence of `True` as a key is chosen. The two are not so easily translatable I guess, considering further conditions usually have the built-in assumption that all preceding conditions were evaluated to false.
- jomohke 3y agobtw, Python has had pattern matching for almost two years now: https://peps.python.org/pep-0622/ https://peps.python.org/pep-0622/ If you support Python 3.10+ you can do this far more cleanly.
- chriswarbo 3y agoTrue, although pattern-matching is unfortunately based on statements, which makes it less useful than if it were an expression (e.g. it can't be used in 'lambda', can't be used in function arguments, can't be used in a dictionary definition, can't be assigned to a variable, can't be used in generator/comprehension, etc.). Also, Python requires explicit returns (unless we're in a lambda), so using a `match` statement for the above example would need multiple duplicate statements (either `return`, or assignment to a repeated variable name, or calling a repeated continuation (although that's less common, due to Python not eliminating tail calls), etc.). A chain of `elif` would also have that problem.
- chimprich 3y ago> (age > 18 and age < 20): "LOL teen emoji amirite?", In Python you can write this more concisely as: (18 < age < 20)
- jtdev 3y ago[dead]
- paulddraper 3y agoIs this any more clear than an elif expression? I suppose the condition coming first is nice
- Izkata 3y agoPersonally I find this a whole lot clearer. It's a table lookup, instead of a series of sequential checks (especially if you listen to your linter and have the elif version with the conditions and values on alternating lines, vs the conditions together in a vertical column like this).
- paulddraper 3y agoNot sure if this was the intent, but to anyone reading this....this dict doesn't have the perf benefits of a "table lookup"; in fact it's slower.
- Izkata 3y agoThe question was about readability, not performance.