4 ms·
I actually would prefer people on my team NOT use these shortcuts. For example: numbers = [1, 2, 3, 4, 5, 6] even = [] for number in numbers: if n
by cnlwsu 14y ago
I actually would prefer people on my team NOT use these shortcuts. For example:
numbers = [1, 2, 3, 4, 5, 6]
even = []
for number in numbers:
if number % 2 == 0:
even.append(number)
is much easier to read and maintain imho then
numbers = [1, 2, 3, 4, 5, 6]
even = [number for number in numbers if number % 2 == 0]
Also:
for x in range(1,101):print"Fizz"[x%3*4:]+"Buzz"[x%5*4:]or x
is a piece of code I never want someone else to write that I may someday have to maintain. Write it out the long way and make your teams lives easier.
- thezilch 14y agoWhile it's OK for you to enforce not using trivial list-comprehensions on your team, I think you'll find the majority of Python's community disagreeing. Your example is really tame as far as comprehensions are concerned, and "beginners" are going to need these basics to comprehend more advanced patterns.
- brown9-2 14y agoIt's especially tame given the friendly variable name chosen.
- tikhonj 14y agoThere is a fundamental difference between the loop and the comprehension: the latter is far more declarative. That is, the comprehension is equivalent to saying something like "even contains every number from numbers that is even". The loop is like saying "start with even as the empty list; for each number in numbers, append it to even". It's much easier to understand what even is from the first description. The for-loop version is much less direct and has too many low-level details--why are you appending to the list and using extra state? From the second definition, you can know what even is just by looking at it; for the first one, you have to think about what the code is doing. This is the fundamental delineation between imperative and declarative code. The former is about how and the latter is about what. In general, specifying the what is much simpler--and therefore easier to write, easier to work with and easier to maintain--than specifying how to get it. I suspect you find the for-loop version easier not because it's simpler but because that's what you're used to. And while familiarity is certainly an important factor, it's always relative and temporary: every person is familiar with different things, and you get more familiar with different constructs over time. Rich Hickey's "Simple Made Easy"[1] talk is a great description of this whole idea. He makes the matter far clearer than I have any hope of doing. [1]: http://www.infoq.com/presentations/Simple-Made-Easy http://www.infoq.com/presentations/Simple-Made-Easy
- Chris_Newton 14y agoThere is a fundamental difference between the loop and the comprehension: the latter is far more declarative. I completely agree with this, and the wider fundamental point throughout your post. However, I’m not a fan of comprehension syntax. It often gets noisy even for trivial cases like this one: the letters “number” appear four times in just a single line here, which as it turns out is just as much accidental complexity as using the explicit loop control variable in the imperative version and you’ve lost the visual cues to what each means that the indentation gives with the loop. For more complicated transformations, I find comprehension syntax also scales poorly. I suspect (though I’ve no hard data to back it up) that comprehension syntax actually isn’t very readable in many cases, and that this may be why some people prefer the kind of code in the imperative example rather than any innate preference for imperative style per se. Personally, I’d prefer to highlight the data flow but using more explicit transformations instead, such as (in a hypothetical functional programming syntax): evens = filter {_ % 2 == 0} numbers Python’s own syntax for this isn’t quite as neat as some functional programming languages, IMHO, but I still prefer it to the comprehension: numbers = [1, 2, 3, 4, 5, 6] evens = filter(lambda n: n % 2 == 0, numbers)
- thezilch 14y agoTo be fair, we should be comparing like tokens, if the proof is using them as part of its advantage: evens = filter(lambda n: n % 2 == 0, numbers) with evens = [n for n in numbers if n % 2 == 0] or evens = [n for n in numbers if not n % 2] Choosing token names is certainly a different
- Chris_Newton 14y agoFair comment. I suppose that’s why a more declarative style tends to work much better in a language designed for it. For example, functional programming languages tend to have neat syntactic sugar for things like simple lambda expressions or applying a series of transformations like the filter here, without introducing accidental complexity like extra identifiers that the reader than has to keep track of. The moment you’ve added that kind of baggage, which is almost inevitable to some degree in a language like Python, the clarity tends to suffer.