更新时间:2022-10-15 18:30:30
根据 文档,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 ***. 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 ***) 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)]