Producing multiple items in a list comprehension

Ivan Illarionov ivan.illarionov at gmail.com
Thu May 22 16:02:13 EDT 2008


On Thu, 22 May 2008 15:29:42 -0400, inhahe wrote:

> "Joel Koltner" <zapwireDASHgroups at yahoo.com> wrote in message
> news:5RiZj.165543$ng7.151222 at en-nntp-05.dc1.easynews.com...
>> Is there an easy way to get a list comprehension to produce a flat list
>> of, say, [x,2*x] for each input argument?
>>
>> E.g., I'd like to do something like:
>>
>> [ [x,2*x] for x in range(4) ]
>>
>> ...and receive
>>
>> [ 0,0,1,2,2,4,3,6]
>>
>> ...but of course you really get a list of lists:
>>
>> [[0, 0], [1, 2], [2, 4], [3, 6]]
>>
>> I'm aware I can use any of the standard "flatten" bits of code to turn
>> this back into what I want, but I was hoping there's some way to avoid
>> the "lists of lists" generation in the first place?
>>
>> A slightly similar problem: If I want to "merge," say, list1=[1,2,3]
>> with list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way
>> with "zip" to do so?
>>
>> Thanks,
>> ---Joel
>>
>>
> i figured out a solution
> 
> sum([x,2*x] for x in range(4)],[]) #not tested sum(zip(list1,list2),())
> #not tested
> 
> (you did say you knew of ways to flatten, but i dunno if you knew of
> that way or not)
> 
> as an aside, i wish that sum didn't have to take the second parameter.
> it's kind of superfluous.  it can just use the first item as the initial
> value instead of 0 when no initial value is specified.   it would be a
> little complex to do without putting a conditional in your main loop and
> slowing it down, but it could be done.


If you don't want the second parameter use reduce():

>>> reduce(operator.add, ([x, x*2] for x in xrange(4)))
[0, 0, 1, 2, 2, 4, 3, 6]

>>> reduce(operator.add, zip([1,2,3],[4,5,6]))
(1, 4, 2, 5, 3, 6)

or:
>>> reduce(lambda x, y: x.extend(y) or x, ([x, x*2] for x in xrange(4)))
[0, 0, 1, 2, 2, 4, 3, 6]

-- Ivan



More information about the Python-list mailing list