Reputation: 5235
How would you delete all starting empty items form a list using list comprehension without deleting empty elements in the middle of list. This is an example:
desc = []
desc.append('')
desc.append('')
desc.append('')
desc.append('line 1')
desc.append('line 2')
desc.append('')
desc.append('')
desc.append('line 3')
filtered = [x for x in desc if x]
filtered
['line 1', 'line 2', 'line 3']
Here is a simple list comprehension that delete all empty items:
filtered = [x for x in desc if x != '']
What I am trying to achieve using list comprehension is something similar to this:
for i in enumerate(desc):
if desc[0].strip() == '':
desc.pop(0)
Upvotes: 2
Views: 529
Reputation: 24133
Use itertools.dropwhile
:
>>> from itertools import dropwhile
>>> lines = ['', '', 'line1', 'line2', '', '']
>>> list(dropwhile(lambda line: not line, lines))
['line1', 'line2', '', '']
Alternatively to the lambda, you could use operator.not_
, as @JonClements suggests:
>>> from operator import not_
>>> list(dropwhile(not_, lines))
['line1', 'line2', '', '']
Upvotes: 6
Reputation: 5275
>>> desc = ['', '', ' ', 'line 1', 'line 2', '', '', 'line 3']
>>> filtered = next(desc[i:] for i in range(len(desc)) if desc[i].strip())
>>> filtered
['line 1', 'line 2', '', '', 'line 3']
The built-in function next
will only iterate till it finds non empty element
in desc list. As soon it finds an element it will stop iteration and will return list from that element till the end instead of iterating whole desc list
.
>>> help(next)
Help on built-in function next in module __builtin__:
next(...)
next(iterator[, default])
Return the next item from the iterator. If default is given and the iterator
is exhausted, it is returned instead of raising StopIteration.
Upvotes: 1
Reputation: 114461
A list comprehension is a nice way to write the creation of a result list only when the decision of which elements to include depend on properties of each sigle element itself.
If the condition depends on other factors (e.g. the position in the result) then probably an explicit loop is more readable instead (and readability is the main point of list comprehensions).
Examples of good use:
Examples that don't fit well the comprehension concept:
Of course you can try to abuse the comprehension to do things they were not designed for, but if the result code is less readable than just writing out the algorithm explicitly then there is no reason to do that.
Upvotes: 1
Reputation: 10192
Other solutions are good. If list comprehension is not necessary then maybe you can try this single line method,
>>> desc
['', '', '', 'line 1', 'line 2', '', '', 'line 3']
>>>
>>> ';'.join(desc).lstrip(';').split(';')
['line 1', 'line 2', '', '', 'line 3']
>>>
Step 1 - Join all elements of the list by some delimiter
>>> x = ';'.join(desc)
';;;line 1;line 2;;;line 3'
Step 2 - Strip delimiters from the starting of the string
>>> x = x.lstrip(';')
'line 1;line 2;;;line 3'
Step 3 - Split the string on delimiter to get the output
>>> x.split(';')
['line 1', 'line 2', '', '', 'line 3']
Upvotes: 1
Reputation: 945
May be you can just translate what you wrote into list comprehensions
filtered = desc[:]
crap = [filtered.pop(0) for i in filtered if filtered[0].strip()==""]
Upvotes: 0