Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带“1”的循环迭代器的单行;如果;过滤器?_Python - Fatal编程技术网

Python 带“1”的循环迭代器的单行;如果;过滤器?

Python 带“1”的循环迭代器的单行;如果;过滤器?,python,Python,愚蠢的问题: 我有一个简单的for循环,后跟一个简单的if语句: for airport in airports: if airport.is_important: 我想知道我是否可以把它写成一行。 所以,是的,我可以做到: for airport in (airport for airport in airports if airport.is_important): 但它读起来是如此愚蠢和多余(对于机场中的机场对于机场中的机场…)。 有更好的方法吗?也许是这样,但它或多或少都是一

愚蠢的问题:
我有一个简单的for循环,后跟一个简单的if语句:

for airport in airports:
    if airport.is_important:
我想知道我是否可以把它写成一行。
所以,是的,我可以做到:

for airport in (airport for airport in airports if airport.is_important):
但它读起来是如此愚蠢和多余(
对于机场中的机场对于机场中的机场…
)。

有更好的方法吗?

也许是这样,但它或多或少都是一样的冗长

import itertools

for airport in itertools.ifilter(lambda x: x.is_important, airports):
    ...
你可以做:

for airport in filter(lambda x: x.is_important, airports):
    # do stuff...
for airport in filter_by_attr(airports, 'is_important'):
    ...
使用列表理解(仅当机场是对象列表时):


这是python的设计理念。如果你花了太多的话才把它写在一行,那么应该把它分成几行,以帮助后面的人。List和generator表达式更适合于就地转换iterables——使
map
filter
的可读性更强。通常,您甚至会将其分成两行:

important_airports = (airport for airport in airports if airport.is_important)
for airport in important_airports:
    # do stuff

这更灵活,更容易阅读,而且仍然不会消耗太多内存。

我会在循环中使用负保护。它是可读的,并且不会引入额外的缩进级别

for airport in airports:
    if not airport.is_important: continue
    <body of loop>
适用于机场中的机场:
如果不是机场。是否重要:继续

以下是一些其他过滤器版本的替代方案:

from operator import attrgetter as attr
for airport in filter(attr('is_important'), airports):
    ...
它的优点是非常简洁,还允许您使用点符号attr('first_class.is_full')

您还可以将类似的内容(或使用列表理解的版本)放入一个实用函数中,如filter\u by\u attr。然后你可以做:

for airport in filter(lambda x: x.is_important, airports):
    # do stuff...
for airport in filter_by_attr(airports, 'is_important'):
    ...
不过,我仍然认为e-satis将其放入一个新变量中是正确的,无论您使用何种方法。这样就更清楚了,尤其是当使用与所讨论的属性的名称不完全匹配(或者标准更复杂)时


我唯一要注意的是,如果您发现自己在多个地方使用此功能,也许您应该将airports设置为一个特殊集合,其中“重要的\u airports”是一个@属性,返回过滤后的集合。或者某种其他抽象来隐藏过滤(比如服务调用)。

我发现过滤器和lambda的使用在一行中是最简单的

for filtered_airport in filter(lambda airport: airport.is_important, airports)):
    print(filtered_airport.some_property)
如果您希望从这个过滤器对象的输出返回一个列表,您可以这样做

filtered_airport_list = list(filter(lambda airport: airport.is_important, airports)))

是的,这也是我能想到的最好的了。@tusbar那又怎样?op要求的是更具可读性的替代方案,而不是更有效的方案。。。差别可以忽略不计(~+-20%),如果我们关心这一利润,我们将用C语言编程,而不是用Python:-实际上,感谢@tusbar!我没有要求它,但它非常有用(作为一个经常优化代码的人)和@fortran:这些微小的差异在一个大项目中很快累积起来。我在片段中添加了我最喜欢的答案,实际上速度更快了!:这是完全错误的,它不做OP所要求的,它迭代布尔值。。。基本上,这是一个地图,不是一个过滤器!它将在布尔列表上迭代。@rogeriopvl:您的更正版本将是OP开始时使用的代码(并且需要一个替代版本)的效率较低的副本。@rogeriopvl现在您的版本与OP相同,只是使用了列表理解而不是迭代器表达式,op要求使用一行如果你不喜欢在一行中有这么多的“airport”,请将其中的三个替换为一个字符:
表示机场in(x表示机场中的x,如果x.is\u重要):
我想知道为什么Python没有表示机场中的机场的
,如果airport.is\u重要:
,它似乎有用且清晰。如果不是airport,也可以使用
。重要的是:继续
,以避免缩进。但是我更喜欢被接受的答案,所以我真的不知道我为什么写这篇评论。一行代码高尔夫不是一个好的做法。谢谢你-我真的很喜欢这个答案。虽然不是一行,但它“抓住了一行的精神”,因为它只有一个缩进(我是否可以说我讨厌缩进,但仍然喜欢Python。不需要额外的导入,通过使用适当的变量名,第二行完全可读(谁在乎我如何实现“重要机场”)。这是我的答案。再次感谢您的及时回复@塔尔维斯当然你可以讨厌凹痕,我也是!根据你名单的大小,或者更确切地说是重要机场的数量,我认为这是最好的方式。它很容易阅读,一旦您了解了
lambda
。自Python 2.4(大约2002年)以来,您可以在中为airport使用和编写
(airport for airport in airport in airport if airport.is重要):
这使得为此目的使用
filter()
有些过时。