tags:

views:

145

answers:

6

Hi I want to write a function that revives a list [1,5,3,6,...] and gives [1,1,5,5,3,3,6,6,...] any idea how to do it? thanks

+6  A: 
>>> a = [1, 2, 3]
>>> b = []
>>> for i in a:
    b.extend([i, i])


>>> b
[1, 1, 2, 2, 3, 3]

or

>>> [a[i//2] for i in range(len(a)*2)]
[1, 1, 2, 2, 3, 3]
SilentGhost
You should use `//` for floor division in Python 2, too.
Mike Graham
@Mike: sure you right, except of course in `/` division insures that `int` is returned.
SilentGhost
+9  A: 
>>> a = range(10)
>>> [val for val in a for _ in (0, 1)]
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]

N.B. _ is traditionally used as a placeholder variable name where you do not want to do anything with the contents of the variable. In this case it is just used to generate two values for every time round the outer loop.

To turn this from a list into a generator replace the square brackets with round brackets.

Dave Kirby
`_` is, these days, used for i18n/l10n (google). I still tend to use it *if* I know there won't be an i18n in this module. Else I (would) use `__` (two underscores).
jae
+1  A: 

I would use

import itertools
foo = [1, 5, 3, 6]
new = itertools.chain.from_iterable([item, item] for item in foo)

new will be an iterator that lazily iterates over the duplicated items. If you need the actual list computed, you can do list(new) or use one of the other solutions.

Mike Graham
or shorter: `itertools.chain.from_iterable(itertools.izip(foo, foo))`
Antony Hatchkins
I considered that code which is shorter but didn't seem clearer to me.
Mike Graham
+5  A: 

If you already have the roundrobin recipe described in the documentation for itertools—and it is quite handy—then you can just use

roundrobin(my_list, my_list)
Hank Gay
+1, this is a good way to accomplish this.
Mike Graham
A: 

For as much as Guido dislikes the functional operators, they can be pretty darned handy:

>>> from operator import add
>>> a = range(10)
>>> b = reduce(add, [(x,x) for x in a])
Just Some Guy
In the case of reduce, handy often means amazingly slow. It's important to measure what `reduce` is doing. Often, it's shocking how much computation reduce forces.
S.Lott
I made a test script with every one of the methods on this page with the baselist = range(10) and 1,000,000 iterations. The slowest took 5.094 seconds and the fastest took 3.622 seconds. My reduce example took 3.906 seconds.
Just Some Guy
`range(10)` is tiny, so the complexity pays a small role. This solution is quadratic; all the others I see here are linear. Also, some of the others seem more readable to me.
Mike Graham
+3  A: 

I would use zip and itertools.chain.

>>> import itertools
>>> l = [1,5,3,6,16]
>>> list(itertools.chain(*zip(l,l)))
[1, 1, 5, 5, 3, 3, 6, 6, 16, 16]

Note: I only used list to consume the generator to make it fit for printing. You probably don't need the list call in your code...

ChristopheD