List with duplicated values and suffix
I have a list, a:
a = ['a','b','c']
and need to duplicate some values with the suffix _ind added this way (order is important):
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
I tried:
b = [[x, x + '_ind'] for x in a] c = [item for sublist in b for item in sublist] print (c) ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
I think my solution is a bit over-complicated. Is there some better, more pythonic solution?
Answers
You could make it a generator:
def mygen(lst): for item in lst: yield item yield item + '_ind' >>> a = ['a','b','c'] >>> list(mygen(a)) ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
You could also do it with itertools.product, itertools.starmap or itertools.chain or nested comprehensions but in most cases I would prefer a simple to understand, custom generator-function.
With python3.3, you can also use yield from—generator delegation—to make this elegant solution just a bit more concise:
def mygen(lst): for item in lst: yield from (item, item + '_ind')
It can be shortened a little bit by moving the options to the inner for loop in the list comprehension:
a = ['a','b','c'] [item for x in a for item in (x, x + '_ind')] # ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
Another alternative with splicing (Python2.x, 3.x):
In [642]: result = [None] * len(a) * 2 In [643]: result[::2], result[1::2] = a, map(lambda x: x + '_ind', a) In [644]: result Out[644]: ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
You can use itertools.chain():
import itertools l = ['a','b','c'] new_list = list(itertools.chain.from_iterable([[i, i+"_ind"] for i in l])) print new_list
Output:
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
Before list comprehensions and generators were invented/became widespread, people used to think much simpler1:
>>> a = ['a', 'b', 'c'] >>> b = [] >>> for x in a: b.extend([x, x+'_ind']) ... >>> b ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
* I don't mean that those constructs/tools are evil, just wanted to point out that there is a simple solution.
Since you asked for "simple", I thought I'd throw this in (albeit, maybe not the pythonic way):
for i in mylist: mylist1.append(i); mylist1.append(i + '_ind');