我正在使用以下列表理解:
resources = [obj.get("file") for obj in iterator if obj.get("file") != None]
有没有办法“缓存”obj.get("file")
在 if 语句中检查时的值,以便在生成返回列表时不必get
再次调用 obj ?
我正在使用以下列表理解:
resources = [obj.get("file") for obj in iterator if obj.get("file") != None]
有没有办法“缓存”obj.get("file")
在 if 语句中检查时的值,以便在生成返回列表时不必get
再次调用 obj ?
resources = filter(None, (obj.get("file") for obj in iterator))
有关如何提供您自己的评估功能的信息,请参阅过滤器文档。传递None
函数(如上)过滤掉所有不正确的值。
如果 obj.get() 返回一个具有奇怪__nonzero__
方法的对象,那么您需要传递lambda obj: obj != None
以获得与原始代码完全相同的结果。
如果您想保留列表/迭代器推导而不是使用filter
,您可以简单地使用:
resources = [file_obj
for file_obj in (obj.get("file") for obj in iterator)
if file_obj is not None]
尝试这样的事情:
resources = filter( lambda x: x is not None, [obj.get("file") for ob jin iterator])
创建一个临时字典来保存值。然后,创建一个将此 dict 用作缓存的函数,并在列表推导中使用该函数,如下所示:
obj_cache = {}
def cache_get (target, key):
if (target, key) not in obj_cache: obj_cache[(target, key)] = target.get(key)
return obj_cache[(target, key)]
resources = [cache_get(obj, "file") for obj in iterator if cache_get(obj, "file") != None]
此外,您可能已经知道这一点(如果是,请忽略此答案),但除非 obj.get("file") 正在进行数据库调用、打开文件、通过网络发出请求或可能做其他事情昂贵,每次迭代调用它两次而不是一次可能是无害的,因为您只是将 O(n) 添加到您的成本中。
从 Python 3.8 开始,可以使用赋值表达式来避免调用函数两次:
iterator = [{'file': 'abc'},
{'file': None},
{'file': 'def'},
{'file': None}]
res = [file for obj in iterator
if (file := obj.get("file")) is not None]
print(res)
# ['abc', 'def']