4 ms·
There are problems I have encountered a billion times and of course I have an elegant concise solution for it, if I am an experienced programmer. if any([a
by atoav 2y ago
There are problems I have encountered a billion times and of course I have an elegant concise solution for it, if I am an experienced programmer.
if any([a in ["-h", "--help"] for a in args]):
display_help()
Would be one of those. Generally I learned that it can be beneficial to treat things as lists early on, e.g. if you have a program that takes one input file it costs you next to nothing to allow the input to be mutiple files as well.
- ckastner 2y agoThat still looks like something that a novice might trip over when reading this. Just describing what it does is already a bit convoluted: it tests whether any value of a list of booleans, produced by a generator expression by testing membership of a value in some other list, is True. I would have gone with the following, as it requires less mental unpacking: if set(args) & set(["-h", "--help"]): display_help() Also, note that any() works with any iterable, the outer brackets are not needed given the list expression. if any(a in ["-h", "--help"] for a in args): display_help()
- dijksterhuis 2y agoon my phone and a bit discombobulated today, so we’ll see how i go with this > That still looks like something that a novice might trip over when reading this. my experience with “juniors” who start with python is that they think in lists and dictionaries. they don’t think in terms of set theory. that’s just the way python is taught. i would definitely set interview questions where a “decent” solution involves using sets and see who gets it without iterating over lists (ha, setting an interview question on sets… geddit? i’ll see myself out). > Just describing what it does is already a bit convoluted yeah, but python only/main “juniors” primarily think in terms of lists, see above. so, between making sure all juniors can read the code versus doing it succinctly, but juniors all need to learn about sets — practicality wins out quite often. > I would have gone with the following, as it requires less mental unpacking: > if set(args) & set(["-h", "--help"]): > display_help() if i were reviewing this code i’d ask you to switch it to if set(args).intersection(set(["-h", "--help"])): it is more verbose and more brackets, but it is more explicit and obvious what is happening to some junior who has never dealt with sets before (hmm what’s an intersection? should probably google it) & is also used for the bitwise AND operator. plus some other stuff in various frameworks like django. so could lead to some confusion. > Also, note that any() works with any iterable, the outer brackets are not needed given the list expression. i generally HATE the overuse of generator expressions in python. everyone writes absolutely everything as an inline generator expression, making it hard to test. but, rant aside, yes, this is probably the one i would pick during a review (likely after a discussion about how using the intersection method makes things less legible and then this gets suggested somewhere). people don’t realise not every genexp needs to be a list. easy mistake to make with the “everything is a list or a dict” mental model.
- Izkata 2y ago".intersection()" takes any iterable, it can be: if set(args).intersection(["-h", "--help"]): Also python has had a special syntax for sets since 2.7 (I think), though I haven't seen it used very often: if {"-h", "--help"}.intersection(args):
- atoav 2y agoIt makes so much sense to think about this as sets, thanks
- nerdponx 2y agoBeing extremely pedantic, omitting the outer ()s is legal for a generator comprehension. That is, the following are equivalent: foo(x for x in xs) foo((x for x in xs)) gen = (x for x in xs) foo(gen) But these are not the same as: foo([x for x in xs] lst = [x for x in xs] foo(lst) It doesn't matter in this tiny example, but the difference between generators and lists can be very very important when working on very large amounts of data (e.g. processing a big text corpus), or a potentially-infinite stream of data.
- nerdponx 2y agoFun Python fact time! `any` works on arbitrary iterables, so you can use a generator comprehension instead of a list comprehension: if any((a in ["-h", "--help"] for a in args)): display_help() Which algorithmically is a wash, because the time you save not-materializing the list, you waste in the overhead of iterating through a generator (and it's all +/- nanoseconds in recent versions of Python anyway). However, Python has a special syntax that allows you to omit a layer of parentheses when a generator comprehension is the only argument to a function, leaving us with the very elegant (IMO) syntax: if any(a in ["-h", "--help"] for a in args): display_help() This works for any(), all(), str.join(), and others. Yet another demonstration of why I think the iteration protocol is one of the best features in Python (and underappreciated as such).
- atoav 2y agoah cool, I didn't realize