Reputation: 2845
This way I can build a new list by mapping every element in another list:
# turn [0,5,10,15] into [1,6,11,16]
[ x+1 for x in range(0,20,5) ]
But I want every element to yield two elements in my new lists. How can I do that? Here are my attempts:
# turn [0,5,10,16] into [0,1,-5,6,-10,11,-15,16]
# does not work! gives [[0,1],[-5,6],[-10,11],[-15,16]]
[ [-x,x+1] for x in range(0,20,5) ]
# turn [0,5,10,16] into [0,1,-5,6,-10,11,-15,16]
# does not work! gives [(0,1),(-5,6),(-10,11),(-15,16)]
[ (-x,x+1) for x in range(0,20,5) ]
Of course I could create the list of lists and then flatten it somehow, but is there a neater way?
Upvotes: 1
Views: 1496
Reputation: 107287
You need to use two loop:
>>> [t for x in range(0,20,5) for t in [-x,x+1] ]
[0, 1, -5, 6, -10, 11, -15, 16]
Or if you are dealing with larger data sets you can use itertools.chain()
>>> from itertools import chain
>>>
>>> list(chain.from_iterable([-x,x+1] for x in range(0,20,5)))
[0, 1, -5, 6, -10, 11, -15, 16]
>>>
Note that if you just want to iterate over the result you don't have to convert the result to list, because chain.from_iterable
returns an iterator and is pretty more optimized in terms of memory usage.
Upvotes: 4
Reputation: 21453
Note that the exact notation you are wanting was proposed but rejected to add to python:
Earlier iterations of this PEP allowed unpacking operators inside list, set, and dictionary comprehensions as a flattening operator over iterables of containers:
>>> ranges = [range(i) for i in range(5)]
>>> [*item for item in ranges]
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
Using this rejected syntax your case would look like:
[ *(-x,x+1) for x in range(0,20,5) ]
however since list comprehension currently only supports a single element at a time you can simply loop over the additional elements as well:
[ item for x in range(0,20,5)
for item in (-x,x+1) ]
Upvotes: 0
Reputation: 2826
You could use functools.reduce
(no need to import it if you are in Python 2.x):
from functools import reduce
flat_list = reduce(lambda x, y: x + y, [[-x, x+1] for x in range(0, 20, 5)], [])
Or, even better, as @Thrustmaster pointed out:
flat_list = sum(([-x, x+1] for x in range(0, 20, 5)), [])
Upvotes: 0
Reputation: 44444
To my knowledge, a list comprehension (with one for
) can not do more than one element at a time. You can either:
from itertools import chain
)Use a function like below and use that as a generator:
def myFunc(elements):
for elem in elements:
yield -elem
yield elem + 1
Upvotes: 2