Python列表理解中的附加条件

时间:2014-12-07 06:18:18

标签: python list-comprehension

如何使用列表理解删除列表中间的空元素从列表中删除所有起始空项目。这是一个例子:

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']

这是一个简单的列表理解,删除所有空项:

filtered = [x for x in desc if x != '']

我想用列表理解实现的目标与此类似:

for i in enumerate(desc):
    if desc[0].strip() == '':
        desc.pop(0)

5 个答案:

答案 0 :(得分:6)

使用itertools.dropwhile

>>> from itertools import dropwhile

>>> lines = ['', '', 'line1', 'line2', '', '']
>>> list(dropwhile(lambda line: not line, lines))
['line1', 'line2', '', '']

除了lambda之外,你可以使用operator.not_,正如@JonClements建议的那样:

>>> from operator import not_

>>> list(dropwhile(not_, lines))
['line1', 'line2', '', '']

答案 1 :(得分:1)

>>> 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']

内置函数next只会迭代,直到在desc列表中找到non empty element。一旦找到一个元素,它将停止迭代,并将从该元素返回列表直到结束而不是迭代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.

答案 2 :(得分:1)

其他解决方案都很好。如果没有必要列表理解,那么也许你可以尝试这种单行方法,

>>> desc
['', '', '', 'line 1', 'line 2', '', '', 'line 3']
>>> 
>>> ';'.join(desc).lstrip(';').split(';')
['line 1', 'line 2', '', '', 'line 3']
>>> 

步骤1 - 通过某些分隔符

加入列表的所有元素
>>> x = ';'.join(desc)
';;;line 1;line 2;;;line 3'

步骤2 - 从字符串

开始删除分隔符
>>> x = x.lstrip(';')
'line 1;line 2;;;line 3'

步骤3 - 在分隔符上拆分字符串以获取输出

>>> x.split(';')
['line 1', 'line 2', '', '', 'line 3']

答案 3 :(得分:1)

只有当决定要包含哪些元素取决于每个sigle元素本身的属性时,列表理解才是编写结果列表创建的好方法。

如果条件取决于其他因素(例如结果中的位置),则可能显式循环更具可读性(可读性是列表推导的主要点)。

良好使用的例子:

  • 所有偶数的列表
  • 尺寸大于一定数量的所有物件
  • 所有不是空元素

不符合理解概念的例子:

  • 前五个偶数(不适合理解,"前五个"部分不依赖于每一个元素)
  • 删除列表开头的空元素(条件取决于其他元素)
  • 唯一元素,即如果元素多次出现则仅保留第一个元素(关于元素的决定取决于之前的决定)。

当然,您可以尝试滥用理解来做他们不是为其设计的事情,但如果结果代码的可读性低于仅仅明确地写出算法,那么就没有理由这样做。

答案 4 :(得分:0)

可能你可以将你写的内容翻译成列表理解

filtered = desc[:]
crap = [filtered.pop(0) for i in filtered if filtered[0].strip()==""]