1

I am trying to figure out if it is possible to make a list comprehension if you create more than one element of the target list in one step.

Lets have a list like this: input_list=['A','B','C/D','E'] and what I want to get in the end is output_list=['A','B','C','D','E'].

This is the piece of code I have now:

output=[]
for x in input:    
    if '/' in x:
        output+=x.split('/')
    else:
        output.append(x)

The only list comprehension that I came up with was: [x.split('/') if '/' in x else x for x in input] but obviously, it is not what I need as it outputs this nested list: ['A','B',['C','D'],'E']

Is it possible, or I just want too much from a simple list comprehension?

Andy S. C.
  • 368
  • 1
  • 4
  • 17
  • You could take your nested list and [flatten](http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python) it. But then you're doing a list comp inside a function, or one list comp inside another one, so it doesn't quite qualify as what you want. – Kevin Feb 03 '15 at 19:59
  • 1
    Not possible in single go until [PEP-448](https://www.python.org/dev/peps/pep-0448/) is not accepted. – Ashwini Chaudhary Feb 03 '15 at 20:02

2 Answers2

2

You could write a list comprehension with two for sections. Whether this is "simple" or not is a matter of opinion.

input_list=['A','B','C/D','E']
print [y for x in input_list for y in (x.split('/') if '/' in x else [x])]

This is effectively equivalent to:

input_list=['A','B','C/D','E']
output = []
for x in input_list:
    if '/' in x:
        sub_list = x.split('/')
    else:
        sub_list = [x]
    for y in sub_list:
        output.append(y)
print output
Kevin
  • 74,910
  • 12
  • 133
  • 166
2

Use a nested list-comprehension:

>>> input_list = ['A','B','C/D','E']
>>> [y for x in input_list for y in (x.split('/') if '/' in x else [x])]
['A', 'B', 'C', 'D', 'E']

Or using itertools.chain.from_iterable:

>>> from itertools import chain
>>> list(chain.from_iterable(x.split('/') if '/' in x else [x] for x in input_list))
['A', 'B', 'C', 'D', 'E']

Note that we need to add [] around a string without / because strings are iterable too.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Which of these two is more efficient concerning memory/speed? – Andy S. C. Feb 03 '15 at 20:13
  • @AndyS.C. Will depend on the number of `/`es present in string, if the inner loop is big then list-comprehension will be slow. – Ashwini Chaudhary Feb 03 '15 at 20:16
  • the `input_list` is only 20 - 40 elements and in some cases all of the elements may have `/`. The problem is, that I have to repeat this operation for ~1M times... – Andy S. C. Feb 03 '15 at 20:21
  • @ AshwiniChaudhary, only up to 3 `/` - in total you can have max 4 characters `'A/C/T/G'` as this is about DNA sequence... – Andy S. C. Feb 03 '15 at 20:26
  • @AndyS.C. For `input_list = ['A/C/T/G'] * 40` the difference is just **0.1µs** for me, so I think you can stick with the LC as it requires no import as well. – Ashwini Chaudhary Feb 03 '15 at 20:30