Meh*_*dad 2 python list set filter python-2.x
为什么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
Run Code Online (Sandbox Code Playgroud)
如
In [1]: s = set([1,2,3])
In [2]: {x%2 for x in s}
Out[2]: {0, 1}
Run Code Online (Sandbox Code Playgroud)
Python 2中的许多"功能"函数都标准化list
为输出类型.这只是很久以前的API选择.在itertools
许多相同的"功能"功能中,标准化提供了一个生成器,您可以从中填充您想要的任何数据结构.在Python 3中,它们标准化了提供迭代器.
But do also note that "filtering" in Python is not like it is in some other languages, like, say Haskell. It's not considered to be a transformation within the context of the data structure, and you don't choose to "endow" your data structures with "filterability" by making them an instance of Functor (or whatever other similar ideas exist in other languages).
As a result, it's a common use case in Python to say something like: "Here's a set, but I just want back all of the values less than 5. I don't care about their 'set-ness' after that point cause I'm just going to do some other work on them, so just give me a ____." No need to get all crazy about preserving the context within which the values originally lived.
在动态打字文化中,这是非常合理的.但是在静态打字文化中,在转换期间保留类型可能很重要,这会有点令人沮丧.从Python的特定角度来看,它实际上只是一种启发式.
如果这是真的只是在一个很窄的范围内set
或tuple
然后我可能只是写一个辅助函数:
def type_preserving_filter(predicate, data):
return type(data)(filter(predicate, data))
Run Code Online (Sandbox Code Playgroud)
如
>>> 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)
Run Code Online (Sandbox Code Playgroud)
它适用于Python 2.10和Python 3.4.在Python 2中,这感觉有点浪费; 从Python 3中的迭代器构造更好.