【问题标题】:Skip entry in generator expression跳过生成器表达式中的条目
【发布时间】:2019-02-28 10:15:44
【问题描述】:

跳过使用函数和另一个生成器创建的生成器表达式中的条目的最佳方法是什么?

本质上,我正在寻找一个看起来像这样的表达式:

some_iter = (some_function(_x, _y, **kwargs) or continue for _x, _y in some_generator(*x))

(但continue 语句显然在这种情况下不起作用)

从功能上讲,它应该是这样的:

def some_iter(*x):
    for _x, _y in some_generator(*x):
        x = some_function(_x, _y, **kwargs)
        if x:
            yield x

【问题讨论】:

  • 你必须使用嵌套生成器:(_x for _x in (function(_x) for _x in generator(*x)) if _x)filter(None, (function(_x) for _x in generator(*x))
  • 在python3.8中可以使用赋值表达式(y := function(_x) for _x in generator(*x) if y)(我觉得)
  • 对了,为什么不使用函数式生成器呢?它工作得非常好并且更具可读性。
  • 我可能最终会使用函数式生成器,但问题的目的是询问是否有一种我可能不知道的使用生成器表达式的方法。如果只有@coldspeed 的答案适用于旧版本的 python!

标签: python expression generator generator-expression


【解决方案1】:

列表推导式允许过滤然后映射。你想先手动map你的函数。

gen = (x for x in map(function, generator(*args)) if x)

以上是针对产生单个参数的generator。你可以使用itertools.starmap,如果它返回一个tuple的参数。

from itertools import starmap

gen = (x for x in starmap(function, generator(*args)) if x)

最后,如果您还需要传入关键字参数,则需要依赖 lambda 函数。

gen = (x for x in map(lambda args: function(*args, **kwargs), generator(*g_args)) if x)

不过,请注意,此时函数样式生成器可能更具可读性。

def gen(*x):
    for args in generator(*x):
        x = some_function(*args, **kwargs)
        if x:
            yield x

【讨论】:

  • function 不是内置的吗?
  • @Chris_Rands Hum 你是对的...... Pycharm 告诉我它是一个,我盲目地相信它
  • @OlivierMelançon 这是一个有用的答案,但请参阅我最近的编辑...如果函数需要多个参数和关键字参数,是否仍然可以应用 map()
  • @omegamanda 不,但在这种情况下你可以使用星图,让我添加一个注释
  • @OlivierMelançon 感谢更新,但我认为这不适用于还需要传递给some_function()的关键字参数
猜你喜欢
  • 2021-08-26
  • 2015-06-08
  • 2021-11-26
  • 2021-03-10
  • 2018-06-20
  • 2016-10-12
  • 1970-01-01
  • 2022-12-03
  • 2017-12-08
相关资源
最近更新 更多