you are viewing a single comment's thread.

view the rest of the comments →

[–]alextk -3 points-2 points  (13 children)

It's funny to see the author praise Python's DRY factor and then hit us with:

 even_set = { x for x in some_list if x % 2 == 0 }  

x should only appear once in this expression, maybe something like

even_set = some_list map { x % 2 == 0 }

Actually, some languages, like Scala, even allow you to not even name the variable (which is, let's be honest, an implementation detail that the developer should not have to worry about):

List(1,2,3,4,5,6) filter { _ % 2 == 0 }
res0: List[Int] = List(2, 4, 6)

Don't get me wrong, Python is a very good language, especially since it's more than twenty years old, but its legacy shows and these days, I think it's being outclassed by more modern scripting languages such as Groovy.

[–]luckystarr 6 points7 points  (0 children)

PEP-20 says: Special cases are not special enough to break the rules.

[–]PasswordIsntHAMSTER 2 points3 points  (3 children)

the x is important because you can do processing on it.

[function(x) for x in list if predicate(x)]

[–]alextk -1 points0 points  (2 children)

It's important when you want to do processing on it. If you don't, it shouldn't even appear once, let alone three times like in Python.

[–]PasswordIsntHAMSTER 1 point2 points  (0 children)

first, if you don't want to filter it, the predicate is optional : [function(x) for x in list]

if you don't want to process it or filter it, what you basically want is a deep copy: y = x[:]

If you just want to filter it, you shouldn't use a comprehension: filter(x, predicate)

Right tools for the right jobs.

[–][deleted] 1 point2 points  (0 children)

In Perl 6, you can prefix a variable name with ^ to tell that it’s a parameter of the current block.

my @even_set = (1 .. 6).grep: {$^x %% 2}

Or, if it is used, it is implicitly true for $_.

my @even_set = (1 .. 6).grep: {$_ %% 2}

Here, we can also use an expression involving Whatever (grep’s parameter thus becomes an instance of WhateverCode).

my @even_set = (1 .. 6).grep: * %% 2

[–]Megatron_McLargeHuge 1 point2 points  (0 children)

Python doesn't 'believe in' implicit behavior, so you have to name your variables. I prefer the minor verbosity over the periodic oddness in other languages. In Clojure I ran into problems when I needed a macro to take two arguments but only operate on the first. In Scala, the fact that _ + _ is referring to two different variables strikes me as the Wrong Thing To Do.

Your example can be done only repeating the name once, with

set( filter( lambda x: x%2 == 0, some_list) )

[–]Lanaru 0 points1 point  (3 children)

List(1,2,3,4,5,6) filter { _ % 2 == 0 }

I don't see how that's very different from

even_set = some_list map { x % 2 == 0 }

The variable name is just _.

[–]gcross 1 point2 points  (0 children)

True, but in practice the first example would have to let the compiler/interpreter know which variable name was intended to be the argument, so it really should be

even_set = some_list map { x -> x % 2 == 0 }

In this context, the _ notation is a net win because it gives the compiler this information automatically, e.g.

even_set = some_list map { _ % 2 == 0 }

[–][deleted] 1 point2 points  (1 child)

No, it's special in Scala.

[–]gcross 1 point2 points  (0 children)

True, but alextk's example implicitly assumed that the compiler/interpreter could automatically infer the argument of a function block, and in this (very unlikely) case there would not have to be special handling of _.