5 ms·
This is something I do instead of writing a long if-else: opt = {0: do_a, 1: do_b, 3: do_b, 4: do_c} opt[option]()
by rnhmjoj 12y ago
This is something I do instead of writing a long if-else:
opt = {0: do_a,
1: do_b,
3: do_b,
4: do_c}
opt[option]()
- baddox 12y agoDo you consider that to be idiomatic? I've been out of touch with the a Python community for a few years, but back then I wouldn't have considered that remotely idiomatic, and if I was on a team writing software, I would have argued that we shouldn't be writing code like that.
- ubernostrum 12y agoIt's not something I see all the time, but using a dictionary instead of a big if/else is something that I'd consider a Python idiom, yes. And it's something I do on occasion. For example: https://github.com/ubernostrum/webcolors/blob/master/webcolors.py#L358 https://github.com/ubernostrum/webcolors/blob/master/webcolo...
- zenciadam 12y agoWhy? It's just a jump-table. In C, you would use function pointers instead of references to functions.
- davidrusu 12y agoI've done this before, I think of it as a more powerful form of a switch statement. I'd love to hear why you think it's not ideal.
- SiVal 12y agoI don't think it's more powerful in any way than an if-elif-elif-else which, for what it's worth, I consider the Pythonic way. Having said that, just because I consider something more Pythonic doesn't mean I prefer it. I've worked in a lot of languages over the years and still work in several in addition to Python. I really enjoy Python, but I prefer techniques that are more universal in many cases. For example, I prefer the idiom of looping over a list index to using Python's "enumerate" in most cases, because index looping is a common cross-language idiom and enumerate usually doesn't offer any benefit I value more than universal obviousness. Other things such as Python's `for item in items` looping style are both VERY Pythonic and much nicer than, say, index looping, so I would almost always prefer such idioms. The above switch -> function pointerish thing is clear to me from years of C/C++, but it is both less generally applicable across languages than if-elif... and less Pythonic, so I would prefer the if-elif... approach. Obviously a matter of preferences, but since you asked....
- aidos 12y agoIt's strange that you would prefer `for item in items` but not `for i, item in enumerate(items)`. So in that case you'd manually do the `for i in range(len(items))...`? I sometimes see this in code and think to myself, whoever wrote this needs to learn themselves some idiomatic python :) I don't think there's much point trying to force stuff that makes sense in one language into another language. Play to a languages strengths and all that. I think you're right about if-elif generally being more powerful than the jump table. Though the jump table is useful in that you can define it in one place and use it in another.
- zo1 12y ago"I'd love to hear why you think it's not ideal." I'm not the poster you posed that question to. But for me, the one big drawback of using that idiom is that the function signatures have to be identical. So you either have to resort to args/kwargs, or you have an additional intermediary method between the actual "guts" of what you're calling, and the "switch" statement. Or you live with the fact that you're passing unused/unnecessary parameters to your functions.
- myg204 12y agoGood point, and in that case, I would say this idiom is not so great really. For functions with the same signature, it's a fine solution I think.
- joyinsky 12y agoBesides you can write code like this s = {'square': lambda x: x **2, 'simple': lambda x: x, 'cube': lambda x: x ** 3} s.get('square', lambda x: 0)(10) s.get('nonexistent', lambda x: 0)(10) Substitute lambdas for real functions and you have a powerful switch case.
- meowface 12y agoIt can be idiomatic in certain circumstances. If your dict keys are just numbers, then no, probably not. But strings mapping to functions, and in some cases objects and other things, are often used to substitute for numerous if and elif statements.
- shabble 12y agoIt's still nicer than the func = getattr(self, 'do_%s' % thing) func(args) I've seen in some codebases :)
- SixSigma 12y agoIt's called a jump table or vtable. It's one of the examples in Forth. Plan 9 uses that technique in C a lot too. This example is ramfs which creates an in memory file system (that you can mount in Unix btw, in 166 LoC) http://swtch.com/usr/local/plan9/src/lib9p/ramfs.c http://swtch.com/usr/local/plan9/src/lib9p/ramfs.c fsopen, fsread, fswrite, fscreate are C functions declared in the same source file : Srv fs = { .open= fsopen, .read= fsread, .write= fswrite, .create= fscreate, }; fs is then passed to a library which calls them as needed.
- vram22 12y agoYes, as SixSigma says, it's called a jump table; I've also seen it called a dispatch table (because you dispatch control to the right function based on a key). It's quite an old technique, dating from the earliest programming languages and even used in assembly language. using indirect addressing and suchlike techniques. Edit: Looked it up, dispatch table is in Wikipedia: http://en.wikipedia.org/wiki/Dispatch_table http://en.wikipedia.org/wiki/Dispatch_table