martina.physics
martina.physics

Reputation: 9804

List comprehension with elements appearing twice

Suppose I have list

l = ['a', 'c', 'b']

and what I want is a list where those elements appear twice, one after the other, so

['a', 'a', 'c', 'c', 'b', 'b']

and I want to do this in the most pythonic way possible.

My half solution is doing something like

[[l[i], l[i]] for i in range(len(l))]

which yields

[['a', 'a'], ['c', 'c'], ['b', 'b']]

From here, I'd have to parse (walk) the list to remove the inner lists and obtain a single flat list.

Anyone has a better idea to do this in one go? Obviously things like l * 2 wouldn't help as it gives ['a', 'c', 'b', 'a', 'c', 'b'] and I want the same elements adjacent.

Upvotes: 3

Views: 1873

Answers (7)

blubberdiblub
blubberdiblub

Reputation: 4135

If you like functional approaches, you can do this:

from itertools import chain, tee

l = ['a', 'c', 'b']
n = 2

list(chain.from_iterable(zip(*tee(l, n))))

While this might not perform as fast as the other answers, it can easily be used for arbitrary iterables (especially when they are infite or when you don't know when they end) by omitting list().

(Note that some of the other answers can also be adapted for arbitrary iterables by replacing their list comprehension by a generator expression.)

Upvotes: 1

Colonel Beauvel
Colonel Beauvel

Reputation: 31181

Here is a short solution without list comprehension, using the intuitive idea l*2:

sorted(l*2, key=l.index)
#['a', 'a', 'c', 'c', 'b', 'b']

Upvotes: 1

UpSampler
UpSampler

Reputation: 399

l_2 = [item for item in l for i in range(n)]

Link to origin: Stackoverflow: Repeating elements of a list n times

Upvotes: 5

Katriel
Katriel

Reputation: 123782

More general:

def ntimes(iterable, times=2):
    for elt in iterable:
        for _ in range(times):
            yield elt

Upvotes: 1

Yousaf
Yousaf

Reputation: 29344

You can use zip function

l = ['a', 'c', 'b']
a = [i for j in zip(l,l) for i in j]
print(a)

Output

['a', 'a', 'c', 'c', 'b', 'b']

Upvotes: 2

Cory Kramer
Cory Kramer

Reputation: 118021

You can zip the list against itself, then flatten it in a list comprehension.

>>> [i for j in zip(l,l) for i in j]
['a', 'a', 'c', 'c', 'b', 'b']

Upvotes: 3

ettanany
ettanany

Reputation: 19826

Using only list comprehension, you can do:

[i for j in my_list for i in [j]*2]

Output:

>>> my_list = ['a', 'c', 'b']
>>> [i for j in my_list for i in [j]*2]
['a', 'a', 'c', 'c', 'b', 'b']

Upvotes: 4

Related Questions