items = [line for line in open('test.txt', 'rb')]
通常,我們會在**中看到一些形似上面的炫目操作(什麼你們覺得很正常?好嘛是我菜了qvq)
我一頭猛紮進了python的懷抱,正是因為「人生苦短,我用python」,可能是相似的原因,我第一眼就看上了這種表達方式,並且樂於在自己的**中使用這種方式來更加精簡與清晰地生成所需要的列表。
由於在專案實現過程中產生過大量的問題與需求,在無數次嘗試之後決定總結一下如何使用列表解析式(也可稱作鍊錶推導式,本文中使用前者,不為什麼,因為覺得這很coooooool呀~)來解決這些型別的問題。
個人覺得吧,循序漸進是個必要的過程,啊啊啊我好懶啊,好想直接貼**就算了啊……
不行,這麼幹的話以後我自己也看不懂的……
那麼稍微解釋一下:
# 寫法如下
ret = [x for j in l for x in j]
# 這個是不是看起來很頭疼?
# 但是實際上我們本來就是為了簡短這種寫法會很常見的
# 為了方便理解大概是下面這種感覺:
ret = [items for sub_list in l for items in sub_list]
# 其含義是:
ret =
for sub_list in l:
for items in sub_list:
# 但是明顯解析式會快得多,
# 與解析式如何生成list的區別這個方向來進行思考。
對於形似如下這種討厭的參差不齊的二維列表,想對其進行flatten操作的時候可以使用簡單的兩層列表解析式搞定(但是對於形似l = [1, [2,3]]
這種的是不行的哦)
l = [
[1,3],
[3],
[1,2,3],
[1,2],
]
# 舉個栗子:
delim = u';'
l = [u'今天是個好天氣!', u'對呀對呀;我也這麼想~']
ret = [x for j in l for x in j.split(delim)]
# 其含義是:
ret =
delim = u';'
for sentence in l:
for items in sentence.split(delim):
# 應用場景例項如下,需求為將傳入句子按分號隔開獲得新的句子列表:
defsplit_list
(l, delim=';'):
if l.__len__() == 0:
return
if isinstance(l[0], unicode) and isinstance(delim, str):
delim = delim.decode('utf-8')
ret = [x for j in l for x in j.split(delim)]
return filter(lambda x: x != '', ret)
在上述例子中,其實只是乙個一維列表,但是我們使用split(delim)
將一維列表中的每個字串變成了乙個列表,此處不僅僅是split,你們還可以自行設定各種更複雜的函式,只不過記得返回值是可迭代的就可以啦~
# 舉個栗子:
dic = ,
2:,}ran = xrange(1,5)
ret = [(k, v) for (k, v) in dic.items() if v['index'] in ran]
# 其含義是:
ret =
for (k,v) in dic.items():
idx = v['index']
if idx in ran:
# 應用例項如下,需求為每次生成滿足條件的子dict,
# 並更新元素中幾個字段表示的在新dict中的位置:
defdict_select
(self, dic, lef, rig=none, pos_lef=none):
""" return a dict which satisfied the range of current segment.
:param dic: a dict
:param lef: left index of word_index
:param rig: right index of word_index
:param pos_lef: left index of position
"""defchange_pos
(inp):
cp = inp.copy() # must be a copy for no-modify
cp[u'word_index'] = inp[u'word_index'] - lef
cp[u'position'] = inp[u'position'] - pos_lef
return cp
if rig:
ran = xrange(lef, rig)
ret = [(k, v) for (k, v) in dic.items() if v[u'word_index'] in ran]
else:
ret = [(k, v) for (k, v) in dic.items() if v[u'word_index'] >= lef]
return dict([(k, change_pos(v)) for (k, v) in ret])
a = [1,2,3]
b = [4,5,6,7]
deffunc
(x):
return x+1
# lambda 為匿名函式,此處的f和func是乙個效果
f = lambda x: x+1
j = lambda x: x%2==1
map(f, a) # 對於list中的每乙個元素做函式f操作
# => [2, 3, 4]
zip(a, b) # 按順序組成pair的list,長度為兩者較短的那個
# => [(1, 4), (2, 5), (3, 6)]
filter(j, a) # 判斷是否滿足條件,輸出滿足條件的list
# => [1, 3]
a.__len__() # 輸出長度,這個要比len()用起來要好些
# => 3
也就是說,在兩層列表解析式中,x, j, l 你們都可以想想怎麼瞎改,
這裡我只試著對x和j改來改去,因為我覺得吧——
你要改傳入的l的話……你為什麼不在外頭改好了再扔進來呢?
# 栗子快舉完了
l = [
(u'a', u'這個句子大概是a類,我也是a類,還有我a類'),
(u'b', u'這個句子大概是b類,我才不告訴你我也是b類'),
(u'a', u'a類吧大概,哼我是a類'),
]ret = [x.strip() for j in l for x in zip(
[j[0]] * len(j[1].split(delim)),
filter(lambda x: x != '', j[1].split(delim))
)]# 其含義是:
ret =
delim = u','
for pair in l:
label, data = pair
items = data.split(delim)
for it in zip([label] * len(items), items):
# 應用場景例項如下,需求為將傳入的(label, data)中的data按逗號隔開
# 並使用共同的label,以獲得新的句子列表:
defsplit_pair
(self, l, delim=','):
if l.__len__() == 0:
return
if isinstance(l[0][1], unicode) and isinstance(delim, str):
delim = delim.decode('utf-8')
return [x for j in l for x in zip(
[j[0]] * len(j[1].split(delim)),
filter(lambda x: x != '', j[1].split(delim))
)]
忙忙碌碌到現在終於有假期了哎~
想著要好好休息休息但是覺得不行趁著餘熱寫點東西要不然我這腦子過兩天就忘乾淨了~
btw. 啊夏活開始了我去看看twitch休息一下下~
Python列表解析式
有時候,乙個程式設計設計模式使用得十分普遍,甚至會逐步形成自己獨特的語法。python程式語言中的列表解析式 list comprehension 就是這類語法糖 syntactic sugar 的絕佳代表。python中的 列表解析式 是個偉大的發明,但是要掌握好這個語法則有些難,因為它們並是用來...
python 列表解析式
python的列表解析式只是為了解決已有問題提供新的語法 什麼是列表解析式?列表解析式是將乙個列表轉換成另乙個列表的工具。在轉換過程中,可以指定元素必須符合一定的條件,才能新增至新的列表中,這樣每個元素都可以按需要進行轉換。可以把列表解析式看作為結合了filter函式與map函式功能的語法糖 dou...
Python列表解析(列表推導式)
列表解析 用來動態地建立列表 expr for iter var in iterable if cond expr 例子一 map lambda x x 2,range 6 0,1,4,9,16,25 x 2 for x in range 6 0,1,4,9,16,25 列表解析式可以取代內建的ma...