Python 3 过滤器 - 错误还是功能? [英] Python 3 filter - Bug or Feature?

查看:30
本文介绍了Python 3 过滤器 - 错误还是功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我是 Python 和 stackoverflow 的完全新手.我来自 ksh 和 Perl 背景.

Python 2.7 交互式会话中的以下内容:

<前>Python 2.7.3(默认,2013 年 1 月 2 日,16:53:07)[GCC 4.7.2] 在 linux2 上输入帮助"、版权"、信用"或许可证"以获取更多信息.>>> 进口重新>>> 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|"... ]) #结束一般列表.>>> 打印(有效值)['REC_PAPER=|YES|NO|']>>>

这是我期望 VALIDVALUES 返回的值.然而,Python 3.2 的交互式会话产生了完全不同的结果:

<前>Python 3.2.3(默认,2013 年 2 月 20 日,17:02:41)[GCC 4.7.2] 在 linux2 上输入帮助"、版权"、信用"或许可证"以获取更多信息.>>> 进口重新>>> 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|"... ]) #结束一般列表.>>> 打印(有效值)<filter 对象在 0xb734268c>>>>

我在几个地方(包括 stackoverflow)看到过,Python 相当于 Perl 对列表的 grep 是过滤列表.这似乎适用于 Python 2.但是,假设 Python 3 中的上述行为是正确的",情况似乎不再如此.

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

第二个问题:假设它是一个特性,我如何获得 Python 2 给出的输出?出于我不会讨论的原因,我不想定义函数或子例程,而是像当前代码一样内联".

我是否遗漏了一些明显的东西(对于新手来说很可能)?提前致谢.

解决方案

根据 文档,Python 3.x 中的filter 返回一个迭代器,而不是2.x 版.这比预先生成整个列表更节省内存.如果您想要返回列表,可以将迭代器包装在 list() 调用中:

VALIDVALUES = list(filter(...))

或者,按照 Python 3.0 中的新功能,您可以将其重写为没有 lambda 的列表推导式:

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

Okay, I am a complete newbie to Python - and stackoverflow. I am coming from a ksh and Perl background.

The following in an interactive session with 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|']
    >>> 

Which is what I would expect VALIDVALUES to return. However, Python 3.2's interactive session yields completely different results:


    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)
    <filter object at 0xb734268c>
    >>> 

I have seen in several places (including stackoverflow) where Python's equivalent of Perl's grep against a list is to filter the list. That appeared to work in Python 2. However, assuming the above behaviour in Python 3 is "correct," that no longer seems to be the case.

First question: Is the above beahviour a bug or feature in Python 3?

Second question: Assuming it is a feature, how do I get the output that Python 2 was giving? For reasons I won't go into, I want to stay away from defining a function or subroutine, and do it "inline" like the current code.

Am I missing something obvious (quite possible for a newbie)? Thanks in advance.

解决方案

As per the documentation, filter in Python 3.x returns an iterator, rather than a list as in version 2.x. This is more memory-efficient than generating the whole list up-front. If you want the list back, you can wrap the iterator in a list() call:

VALIDVALUES = list(filter(...))

Alternatively, and as recommended by What’s New In Python 3.0, you could rewrite it as a list comprehension without a lambda:

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

这篇关于Python 3 过滤器 - 错误还是功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆