簡體   English   中英

為什么Python的過濾器(謂詞,集合)不返回集合?

[英]Why doesn't Python's filter(predicate, set) return a set?

為什么要設計Python的filter ,使得如果運行filter(my_predicate, some_set) ,我得到的list對象返回的不是set對象?
在實際情況下,您希望將結果set ...嗎?

您可以進行設定的理解。

{my_predicate(x) for x in some_set}      # mapping
{x for x in some_set if my_predicate(x)} # filtering

In [1]: s = set([1,2,3])

In [2]: {x%2 for x in s}
Out[2]: {0, 1}

Python 2中的許多“功能”函數都以將list作為輸出類型進行了標准化。 這只是很久以前的API選擇。 itertools許多相同的“功能”函數都標准化了提供生成器的功能,您可以從該生成器中填充所需的任何數據結構。 並且在Python 3中,它們在提供迭代器上是標准化的。

但也請注意,Python中的“過濾”與其他語言中的“過濾”不同,例如Haskell。 它不被認為是數據結構的上下文一個轉變,你沒有選擇,使它們函子的一個實例,“賦予”您的數據“過濾性”結構(或任何其它類似的想法在其他語言中存在) 。

結果,這是Python中的一個常見用例,它說:“這是一個集合,但是我只想返回所有小於5的值。在此之后,我不在乎它們的“設置”我將對它們進行其他工作,所以請給我一個____。” 無需為保存值最初存在的上下文而瘋狂。

在動態打字文化中,這是非常合理的。 但是在靜態類型文化中,在轉換期間保留類型可能很重要,這會令人感到沮喪。 從Python的特定角度來看,這實際上只是一種啟發。

如果確實只是在settuple的非常狹窄的上下文中,那么我可能只寫了一個輔助函數:

def type_preserving_filter(predicate, data):
    return type(data)(filter(predicate, data))

>>> type_preserving_filter(lambda x: x > 3, set([1,2,3,4,5,6,7,7]))
{4, 5, 6, 7}
>>> type_preserving_filter(lambda x: x > 3, list([1,2,3,4,5,6,7,7]))
[4, 5, 6, 7, 7]
>>> type_preserving_filter(lambda x: x > 3, tuple([1,2,3,4,5,6,7,7]))
(4, 5, 6, 7, 7)

在Python 2.10和Python 3.4中均可使用。 在Python 2中,這有點浪費。 使用Python 3中的迭代器進行構造會更好。

這不限於filter() 但是API已在Python 3中進行了更改,其中filter()現在返回迭代器而不是列表。 引用python文檔:

視圖和迭代器而不是列表

一些著名的API不再返回列表:

...

  • map()filter()返回迭代器。 如果您確實需要列表,則快速修復方法是例如list(map(...)) ,但是更好的解決方法通常是使用列表理解(尤其是當原始代碼使用lambda時),或者重寫代碼以使其不根本不需要列表。 為函數的副作用調用map()尤其棘手; 正確的轉換是使用常規的for循環(因為創建列表將很浪費)。

由Python的作者撰寫的這篇文章詳細介紹了在Python 3中刪除filter()原因(但是,盡管推理仍然很重要,但這並未如您在上面看到的那樣發生。)

Python 3000中reduce()的命運

...

我認為刪除filter()map()毫無爭議; filter(P, S)幾乎總是更清楚地寫為[x for x in S if P(x)] ,這具有巨大的優勢,即最常用的用法是比較謂詞,例如x==42 ,並定義一個lambda只是需要讀者付出更多的努力(加上lambda比列表理解要慢)。 對於map(F, S)甚至更是如此map(F, S)它成為[F(x) for x in S] map(F, S) [F(x) for x in S] 當然,在許多情況下,您可以改為使用生成器表達式。

暫無
暫無

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

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