簡體   English   中英

列表理解以創建列表

[英]List comprehension to create a list

可以使用列表理解更緊湊地編碼以下內容嗎?

labels=[]
for i in range(10):
    labels=labels+[i]+9*['']
labels=labels+[10]

這是一種分解方法。

如果查看循環的主體,則可以將其重組為為每個數字生成一個子列表,然后將這些子列表組合在一起。

sublists = []
for i in range(10):
  sublists.append([i] + 9 * [''])

labels = []
for sublist in sublists:
  labels = labels + sublist

labels = labels + [10]

第一部分包含一個數字列表,在每個數字上調用相同的函數,並生成結果列表。 此操作是map (實際上在許多語言中都有此名稱)。 第二部分獲取一個列表列表,並將它們展平為一個大列表。 許多語言都有“ concat”或“ flatten”操作,但在Python 中可能有點笨拙

from itertools import chain
sublists = map(range(10), lambda i: [i] + 9 * [''])
labels = list(chain.from_iterable(sublists))
labels = labels + [10]

map()調用特別容易轉換為列表理解(或生成器理解)

from itertools import chain
sublists = [[i] + 9 * [''] for i in range(10)]
labels = list(chain.from_iterable(sublists))
labels = labels + [10]

因此,如果您想將其變成單線,則可以

from itertools import chain
labels = list(chain.from_iterable([i] + 9 * [''] for i in range(10))) + [10]

對於完全不同的東西,您可能會使用生成器函數來使自己的工作更清晰。 實際上,對於輸入中的每個項目,您正在發出該項目,如果不是最后一個項目,則發出包含空字符串的九個列表。 然后,您可以采用generator函數產生的序列並將其轉換為列表。

def emit_with_blanks(iter):
  l = list(iter)
  for i, n in enumerate(l):
    yield [i]
    if i == len(l) - 1:
      break
    for _ in range(9):
      yield ['']

labels = list(emit_with_blanks(range(10))

這肯定更長,也更慢(在實踐中這應該無關緊要),但是比起單線來說,可以更容易地推斷出它在做什么,尤其是如果您六個月后回到那里並試圖記住的話代碼究竟是做什么的。

它令人費解,但是如果您想要列表理解,這是一種實現方法:

[i for s in [[x] + 9*[''] if x < 10 else [x] for x in range(11)] for i in s]

演示:

>>> labels = [i for s in [[x] + 9*[''] if x < 10 else [x] for x in range(11)] for i in s]
>>> labels
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

通過比較:

>>> labels=[]
>>> for i in range(10):
...     labels=labels+[i]+9*['']
... 
>>> labels=labels+[10]
>>> labels
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

這是您要查找的代碼

labels=[j for i in range(10) for j in [i]+9*['']]+[10]

這對我來說就像是“創建一個長度為101個元素的數組,其中每個項目的索引為10的非整數倍,則為空字符串,否則為索引除以10”。 作為列表理解:

>>> ['' if i % 10 else i / 10 for i in xrange(101)]
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

就是說,如果列表理解不是絕對必要的,我發現類似這樣的東西會更容易理解:

>>> y = []
>>> for i in xrange(10):
...     y.append(i)
...     y.extend([''] * 9)
...
>>> y.append(10)

(與您的原始方法幾乎相同)

暫無
暫無

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

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