簡體   English   中英

Python列表理解與Perl中的map / grep是一回事嗎?

[英]Are Python list comprehensions the same thing as map/grep in Perl?

我在使用Python中的列表理解語法時遇到了一些麻煩,所以我開始考慮如何在Perl中實現相同的功能,我更熟悉它。 我意識到基本的例子(取自本頁 )都可以在Perl中用mapgrep

例如

(python)                            (perl)                  
S = [x**2 for x in range(10)]       @S = map { $_**2 } ( 0..9 );
V = [2**i for i in range(13)]       @V = map { 2**$_ } ( 0..12 );
M = [x for x in S if x % 2 == 0]    @M = grep { $_ % 2 == 0 } @S;

那么“列表理解”只是“地圖和/或過濾列表”的一個奇特術語,還是更多呢?

你是對的:列表推導基本上只是地圖和過濾器的語法糖(來自函數式編程世界的術語)。

希望此示例代碼演示它們的相等性:

>>> # Python 2
>>> [x**2 for x in range(10)] == map(lambda x: x**2, range(10))
True
>>> [2**i for i in range(13)] == map(lambda x: 2**x, range(13))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == filter(lambda x: x % 2 == 0, S)
True

請注意,這僅在Python 2.X中有效,正如SilentGhost在注釋中指出的那樣。 為了使其與Python 3兼容,您必須在list構造函數中包含對map或filter的調用,因為map和filter已更新為返回迭代器而不是列表。

>>> # Python 3
>>> [x**2 for x in range(10)] == list(map(lambda x: x**2, range(10)))
True
>>> [2**i for i in range(13)] == list(map(lambda x: 2**x, range(13)))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == list(filter(lambda x: x % 2 == 0, S))
True

是的,它們基本相同。

實際上Python也有一個map函數:

S = map(lambda x: x**2, range(10))

與上面的第一個例子相同。 但是,列表推導語法在Python中是首選。 我相信Guido被引用說他遺憾地介紹了功能語法。

然而,它真正有趣的地方在於列表推導的下一個演變,即生成器。 這些允許您返回迭代器 - 而不是一次處理整個列表,它只進行一次迭代然后返回,這樣您就不必同時將整個列表保存在內存中。 很強大。

它們是用於映射和過濾序列的“pythonic”版本,但它們允許執行其他一些操作,例如展平(固定級別)嵌套列表,例如:

[j for i in nested_list for j in i]

使用常規映射和lambda表達式無法做的另一件事是在結構上分解迭代值,例如:

[(x%y)*z for x,y,z in list_with_triplets_of_ints]

當然有一些解決方法,如:

aux = lambda x,y,z: (x%y)*z
map(lambda t: aux(*t), list_with_triplets_of_ints)

但是當你需要應用的轉換已經定義時,通常使用地圖會更簡單,例如:

map(int, list_of_str_values)

而不是

[int(i) for i in list_of_str_values]

列表理解也使事情變得平淡:

例如:

[(x,y)x中x(10)如果x%2 == 0表示x中的y(20)如果x!= y]

如果你在這里使用嵌套映射,你也必須使用concat(匯總列表)。

列表推導比映射或過濾更強大,因為它們允許您抽象地使用列表。

當您的地圖進一步嵌套更多地圖和過濾器調用時,使用它們也更方便。

是。 Python語法的強大之處在於,相同的語法(在圓形而不是方括號內)也用於定義生成器,生成器按需生成值序列。

暫無
暫無

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

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