【问题标题】:Generator for many various items许多不同项目的生成器
【发布时间】:2020-06-12 15:05:41
【问题描述】:

有一个包含许多不同项(函数、对象属性、值)的数组,例如:

lst = [
 1,
 a(),
 obj.prop,
 ...

 z()
]

我想检查所有值是否为真,所以我使用all()

all(lst)

但在这种情况下,列表的所有值都是在创建列表时计算的。

目的是不计算列表初始化时的所有值,而是“即时”计算并停止迭代(并计算)列表中的第一个 False 项。所以一种解决方案是从生成器中产生每个值:

def gen():
 yield 1
 yield a()
 yield obj.prop
 ...

 yield z()

但它不是干代码,重复的 yield 关键字看起来很难看。还有其他更漂亮的解决方案吗?

【问题讨论】:

  • 代码很丑,因为“一个包含各种项目的数组”一开始就很丑,你只在每一行添加了yield关键字。如果定义此列表的最佳方法是按照您所显示的那样逐字写出每个元素,那么不:没有更漂亮的方式将其编写为生成器,可以支持您在第一个元素之后停止评估元素的要求找到 false (all 为你做 stackoverflow.com/questions/14730046/…

标签: python generator dry yield


【解决方案1】:

我将因发布此内容而被否决,但如果您可以将函数和参数拆分为一个元组列表(如果不是真正的函数,则使用 params=None),这样的事情会起作用。 但正如人们在 cmets 中所说的那样,这些数据很难看。再想想这些函数是在被添加到列表之前来自的,如果可能的话,在生成列表之前尝试一一评估它们。

def a(z):
    print('a')
    return True
def b(z):
    print('b')
    return False
def c(z):
    print('c')
    return True

def map_func_params(x):
    for func, params in x:
        if params is None:
            if func:
                continue
        if func(*params):
            continue
        else:
            return False
    return True

print(
map_func_params([(a, (1,)), (b, (2, )), (c, (2, )), (4, None)])
)

打印显示:

a
b
False

并且函数 c 永远不会执行。

【讨论】:

  • 这处理函数,但不处理变量,例如obj.prop - 可以使用getattr 重写对象属性,简单的变量需要一个包装函数:def get_a(): return a
  • 不仅仅是函数调用,还有对象属性会导致在求值时执行任意代码
猜你喜欢
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多