簡體   English   中英

Python列表理解中的附加條件

[英]Additional condition in 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)

使用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', '', '']
>>> 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只會重復,直到它找到non empty element desc中列表。 一旦找到一個元素,它將停止迭代,並將從該元素返回列表直到結束,而不是迭代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.

其他解決方案都很好。 如果沒有必要列表理解那么你可以嘗試這種單行方法,

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

只有當決定要包含哪些元素取決於每個sigle元素本身的屬性時,列表理解才是編寫結果列表創建的好方法。

如果條件取決於其他因素(例如結果中的位置),則可能顯式循環更具可讀性(可讀性是列表推導的主要點)。

好用的例子:

  • 所有偶數的列表
  • 所有尺寸大於一定數量的物體
  • 所有不是空元素

不符合理解概念的例子:

  • 前五個偶數(不理解,“前五個”部分不依賴於每一個元素)
  • 刪除列表開頭的空元素(條件取決於其他元素)
  • 唯一元素,即如果元素多次出現則僅保留第一個元素(關於元素的決定取決於先前的決定)。

當然,你可以嘗試濫用理解來做他們不是為他們設計的東西,但如果結果代碼的可讀性低於僅僅明確寫出算法,那么沒有理由這樣做。

也許你可以將你寫的內容翻譯成列表推導

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM