Python 3过滤器 - Bug还是功能?

问题描述 投票:0回答:2

好的,我是Python的新手 - 和stackoverflow。我来自ksh和Perl背景。

以下是与Python 2.7的交互式会话:


    Python 2.7.3 (default, Jan  2 2013, 16:53:07) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import re
    >>> KEY="REC_PAPER"
    >>> VALIDVALUES=filter(lambda x:re.search(r'^' + KEY + '\=', x), [
    ... "REC_METAL=|YES|NO|",
    ... "REC_PAPER=|YES|NO|",
    ... "REC_GLASS=|YES|NO|",
    ... "REC_PLAST=|YES|NO|",
    ... "DEBUG_FLAG=|0|1|"
    ... ])  #End general list.
    >>> print(VALIDVALUES)
    ['REC_PAPER=|YES|NO|']
    >>> 

这是我期望VALIDVALUES返回的。但是,Python 3.2的交互式会话会产生完全不同的结果:


    Python 3.2.3 (default, Feb 20 2013, 17:02:41) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import re
    >>> KEY="REC_PAPER"
    >>> VALIDVALUES=filter(lambda x:re.search(r'^' + KEY + '\=', x), [
        ... "REC_METAL=|YES|NO|",
        ... "REC_PAPER=|YES|NO|",
        ... "REC_GLASS=|YES|NO|",
        ... "REC_PLAST=|YES|NO|",
        ... "DEBUG_FLAG=|0|1|"
        ... ])  #End general list.
    >>> print(VALIDVALUES)
    &ltfilter object at 0xb734268c>
    >>> 

我已经在几个地方看到过(包括stackoverflow),其中Python相当于Perl对列表的grep是过滤列表。这似乎在Python 2中有效。但是,假设Python 3中的上述行为是“正确的”,那似乎不再是这种情况。

第一个问题:上述行为是Python 3中的错误还是功能?

第二个问题:假设它是一个功能,我如何获得Python 2提供的输出?由于我不打算进入的原因,我想远离定义函数或子例程,并像当前代码一样“内联”。

我错过了一些明显的东西(很可能是新手)?提前致谢。

python-2.7 python-3.x filter grep
2个回答
3
投票

根据the documentation,Python 3.x中的filter返回迭代器,而不是像version 2.x中的列表。这比预先生成整个列表更具内存效率。如果您想要返回列表,可以将迭代器包装在list()调用中:

VALIDVALUES = list(filter(...))

或者,根据What’s New In Python 3.0的建议,您可以将其重写为没有lambda的列表理解:

VALIDVALUES = [x for x in [...] if re.search(r'^' + KEY + '\=', x)]

1
投票

请注意,您通常不需要值列表。您可以直接循环输出,如下所示

for value in VALIDVALUES:
  do_some_thing(value)

要么

for value in filter(...):
  do_some_thing(value)

有时您可能需要唯一值或非可变值。使用settuplefrozenset代替list,如other answer所示。

© www.soinside.com 2019 - 2024. All rights reserved.