So, I was trying to learn Elm (I just gave up), then I saw this feature request:
I suggest that list comprehensions be added to Elm. They see heavy use in languages that implement them. Considering the existing similarities between Elm and Haskell syntax, I propose using Haskell style list comprehensions, like this:
[(x, y) | x <- [1..10], y <- [1..20], x /= y]
</div> <div class="gh-btn-container"><a class="gh-btn" href="https://github.com/elm/compiler/issues/147">View on GitHub</a></div>
I was trying to find an alternative to
list comprehensionin Elm, they was recommending to use
map. List comprehension is just a Syntactic Sugar. Then let's compare both of them in Python.
lambdef lab λ python -m timeit "map(lambda a: a*a, range(100))" 100000 loops, best of 3: 11.5 usec per loop
List comprehension performance:
lambdef lab λ python -m timeit "[a*a for a in range(100)]" 100000 loops, best of 3: 5.51 usec per loop
List comprehension is 2x faster!
List comprehension looks more concise and beautiful than map.
[n for n in nlist]| | | map(lambda n: n, nlist)
It's 5 bytes larger and slower! Bad!
There is dis to show Python Bytecode of Python code. Let's see the bytecode of
list comprehension and
map to compare the performance.
Bytecode of [n for n in range(100)] (List comprehension) 1 0 LOAD_CONST 0 (<code object <listcomp> at 0x7f042c8eac00, file "<dis>", line 1>) 2 LOAD_CONST 1 ('<listcomp>') 4 MAKE_FUNCTION 0 6 LOAD_NAME 0 (range) 8 LOAD_CONST 2 (100) 10 CALL_FUNCTION 1 12 GET_ITER 14 CALL_FUNCTION 1 16 RETURN_VALUE
It loads list comprehension, creates function, loads range function and loads 100 to give it as argument, calls range function, and returns the value.
Bytecode of map(lambda n: n, range(100)) (Map) 1 0 LOAD_NAME 0 (map) 2 LOAD_CONST 0 (<code object <lambda> at 0x7f042c8ead20, file "<dis>", line 1>) 4 LOAD_CONST 1 ('<lambda>') 6 MAKE_FUNCTION 0 8 LOAD_NAME 1 (range) 10 LOAD_CONST 2 (100) 12 CALL_FUNCTION 1 14 CALL_FUNCTION 2 16 RETURN_VALUE
It loads map function, it loads the lambda (
lambda n: n), makes the lambda function object, loads range function and loads 100 to give it as argument, calls two functions and returns the value.
In my opinion, Python Bytecode is understandable by humans™.
- Support for generating lists directly
- Support for generating generators directly
- Filtering (ifs)
- No cons! (IMO)
- No pros! (IMO)
- Generates only map object (You need to turn it into the object you want later)
- No ifs (filtering)
- Double each number to 100
# List comprehension [n*2 for n in range(100)] # Map map(lambda n: n*2, range(100))
fnto each number to 100
# List comprehension [fn(n) for n in range(100)] # Map map(fn, range(100))
- Filter evens
# List comprehension [n for n in range(100) if n % 2 == 0] # Map not_possible() # But you can use filter: # filter(lambda n: n % 2 == 0)
list comprehension over
map while optimizing your code.
Thanks for reading!