1

I have a list which is produced by a list comprehension and it sorts the data in stripped according to groups by finding which strings have a length of 3 and I want to merge them so that are in a single list separately from single length strings.

stripped = ['a,b', 'c,d', 'e', '', 'f,g', 'h', '', '']
lst = [[i.split(',')] if len(i) is 3 else i for i in stripped]
print(lst)
#[[['a', 'b']], [['c', 'd']], 'e', '', [['f', 'g']], 'h', '', '']

I want to produce [[['a', 'b'], ['c', 'd'],['f', 'g']], 'e', '','h', '', ''] instead

How can I achieve this with a Single list-comprehension if possible?

Edit:

accepted @HennyH's answer because of its high efficiency and simplicity

Community
  • 1
  • 1
K DawG
  • 13,287
  • 9
  • 35
  • 66

3 Answers3

4
l = [[]]
for e in stripped:
    (l[0] if len(e) == 3 else l).append(e)
>>> 
[['a,b', 'c,d', 'f,g'], 'e', '', 'h', '', '']

Or to match the OP's output for the 3 long strings:

for e in stripped:
    l[0].append(e.split(',')) if len(e) == 3 else l.append(e)
>>> 
[[['a', 'b'], ['c', 'd'], ['f', 'g']], 'e', '', 'h', '', '']

This way there is no additional concatenation of two lists A,B as Inbar's solution provided. You can also turn stripped into a generator expression so you don't need to hold the two lists in memory.

HennyH
  • 7,794
  • 2
  • 29
  • 39
2

Use two list comprehensions:

>>> stripped = ['a,b', 'c,d', 'e', '', 'f,g', 'h', '', '']
>>> first = [x.split(',') for x in (item for item in stripped if len(item) == 3)]
>>> second = [item for item in stripped if len(item) != 3]
>>> [first] + second
[[['a', 'b'], ['c', 'd'], ['f', 'g']], 'e', '', 'h', '', '']
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

Why require list comprehension? Better to do it in 1 pass.

stripped = ['a,b', 'c,d', 'e', '', 'f,g', 'h', '', '']
groups = []
final = [groups]
for item in stripped:
    if len(item) == 3:
        groups.append(item.split(','))
    else:
        final.append(item)

Result:

>>> print(final) 
[[['a', 'b'], ['c', 'd'], ['f', 'g']], 'e', '', 'h', '', '']
Inbar Rose
  • 41,843
  • 24
  • 85
  • 131