4 ms·
values = list(filter(None, [line.strip() for line in buffer.readlines()]))
by weird-eye-issue 4y ago
values = list(filter(None, [line.strip() for line in buffer.readlines()]))
- pmontra 4y agoOr, in a different language open("file", "r").readlines. map{|line| line.strip}. filter{|line| line != ""} or some smarter but less readable ways. I prefer the left-to-right transformations style to Python's list comprehension and inside-to-outside function composition. The reason is that it reminds me of how data flow into *nix pipelines. I spent decades working with them and I've been working with Ruby for the last half of that time. With Python in the last quarter of my career. It's a matter of choices and preferences of the original designed of the language. Both ways work.
- quietbritishjim 4y agoNot sure if this was your intention or not, but to me that proves the usefulness of the walrus operator: the first snippet in the parent comment seems far clearer to me, even though I'm fairly familiar with the functional operators.
- weird-eye-issue 4y agoIt's a very useful pattern once you know what it does, sort of like the walrus operator
- quietbritishjim 4y agoI was careful to pre-empt this exact response in my original comment: I do know what it does. The fact remains that it's less readable (IMO) because of the density of line noise and the lack of common structural elements (like if and for - I suppose filter and map fulfill this but their parameter separate out elements that ought to be next to each other). I do think that my preference, however slight, would remain no matter how much time I spent with the functional versions.
- weird-eye-issue 4y agoI'm glad you know what it does but you weren't born knowing what the walrus operator does either
- zelphirkalt 4y agoWhat does `filter` do with `None`? Would it not be an error? This seems not so readable, possibly relying on weird behavior of `filter`. If I had to guess, I would say: Maybe filter with `None` will give the empty list or the whole list, because either no list item matches a `None` condition, or all match it, since there is no condition. But in both cases the usage does not seem to make any sense. So it must be something else. Maybe when the argument is not a lambda, it will compare directly with the given argument? But then we would get only `None`. Nah, still makes no sense. I am at a loss, what this `filter` call is doing, without trying it out.
- weird-eye-issue 4y agoFrom the docs: If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed. So it just removes false-y values. Very handy I've used it a ton
- dragonwriter 4y ago> What does `filter` do with `None`? filter(None, xs) is equivalent to: filter(lambda x: x, xs) That is, it will return an iterator over the truthy elements of the passed iterable.
- quietbritishjim 4y agoI suspect the question was rhetorical. The point is, every reader is going to have that question pop into their head and have to look it up. Better to use code that doesn't raise any questions, even if it's a few more characters.
- dragonwriter 4y ago> Better to use code that doesn't raise any questions, even if it's a few more characters. Certainly, I agree; I would usually use: (x for x in xs if x) Or, if I know more about the kind of falsy values xs actually needs removed, something more explicit like: (x for x in xs if x is not None) Because Python’s multiplicity of falsy values can also be something of a footgun (particularly, when dealing with something a collection of Optionals where the substantive type has a falsy value like 0 or [] included.) Instead of: filter(None, xs) Which is terse but potentially opaque. Though it's additional syntax, I kind of wish genexp/list/set comprehensions could use something like “x from” as shorthand for “x for x in”, which would be particularly nice for filtering comprehensions.