仅将列表推导用于副作用是否符合 Pythonic?

2024-11-20 08:44:00
admin
原创
12
摘要:问题描述:考虑一下我调用的函数的副作用,而不是返回值(例如打印到屏幕、更新 GUI、打印到文件等)。def fun_with_side_effects(x): ...side effects... return y 现在,使用列表推导来调用这个函数是否符合 Pythonic风格:[fun_wi...

问题描述:

考虑一下我调用的函数的副作用,而不是返回值(例如打印到屏幕、更新 GUI、打印到文件等)。

def fun_with_side_effects(x):
    ...side effects...
    return y

现在,使用列表推导来调用这个函数是否符合 Pythonic风格:

[fun_with_side_effects(x) for x in y if (...conditions...)]

请注意,我没有保存该列表

或者我应该像这样调用这个函数:

for x in y:
    if (...conditions...):
        fun_with_side_effects(x)

哪一个更好?为什么?


解决方案 1:

这样做非常违反 Python 规范,任何经验丰富的 Pythonista 都会因此而责怪你。中间列表在创建后会被丢弃,而且它可能非常非常大,因此创建起来非常昂贵。

解决方案 2:

您不应该使用列表推导,因为正如人们所说,这将构建一个您不需要的大型临时列表。以下两种方法是等效的:

consume(side_effects(x) for x in xs)

for x in xs:
    side_effects(x)

consume使用手册页中的定义itertools

def consume(iterator, n=None):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

当然,后者更加清楚,也更容易理解。

解决方案 3:

列表推导用于创建列表。除非您确实要创建列表,否则不应使用列表推导。

因此我会选择第二种选择,只需遍历列表,然后在条件适用时调用该函数。

解决方案 4:

第二个更好。

想想那些需要理解你的代码的人。对于第一个人来说,你很容易得到坏的报应 :)

你可以使用 filter() 在两者之间找到折中方案。请考虑以下示例:

y=[1,2,3,4,5,6]
def func(x):
    print "call with %r"%x

for x in filter(lambda x: x>3, y):
    func(x)

解决方案 5:

取决于你的目标。

如果您尝试对列表中的每个对象执行某些操作,则应采用第二种方法。

如果您尝试从另一个列表生成一个列表,则可以使用列表推导。

明确优于隐含。简单优于复杂。(Python Zen)

解决方案 6:

你可以做

for z in (fun_with_side_effects(x) for x in y if (...conditions...)): pass

但不太漂亮。

解决方案 7:

使用列表推导式来实现它的副作用是丑陋的、非 Python 的、低效的,我不会这么做。我会使用循环for,因为for循环表明了一种程序风格,其中副作用很重要。

但是,如果你坚持使用列表推导式来消除其副作用,那么你应该改用生成器表达式来避免效率低下的问题。如果你坚持使用这种风格,请执行以下两项操作之一:

any(fun_with_side_effects(x) and False for x in y if (...conditions...))

或者:

all(fun_with_side_effects(x) or True for x in y if (...conditions...))

这些是生成器表达式,它们不会生成随机列表并被丢弃。我认为这种all形式可能更清晰一些,尽管我认为它们都令人困惑,不应该使用。

我认为这很丑陋,我不会在代码中真正做到这一点。但如果你坚持以这种方式实现循环,我就会这样做。

我倾向于认为列表推导及其同类应该表明尝试使用至少与函数式风格略微相似的东西。将具有副作用的东西放入其中会破坏这一假设,这将导致人们不得不更仔细地阅读你的代码,我认为这是一件坏事。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   609  
  在现代项目管理中,资源的有效利用是确保项目成功的关键因素之一。随着技术的不断进步,越来越多的工具和软件被开发出来,以帮助项目经理和团队更高效地管理资源。本文将介绍10款工具,这些工具可以帮助项目团队提升资源利用效率,从而实现项目目标。禅道项目管理软件禅道项目管理软件是一款开源的项目管理工具,广泛应用于软件开发和其他行业...
项目管理系统   3  
  在项目管理领域,软件工具的不断升级和创新是推动效率和协作的关键。2024年,众多项目管理软件将迎来一系列令人期待的升级功能,这些新特性不仅将提升团队的工作效率,还将增强用户体验和数据分析能力。本文将详细介绍10款项目管理软件的最新升级功能,帮助项目经理和团队成员更好地规划和执行项目。禅道项目管理软件禅道项目管理软件一直...
开源项目管理工具   2  
  信创国产系统的10个关键厂商及其技术生态随着全球信息技术格局的不断演变,信创(信息技术应用创新)产业作为国产化替代的重要阶段,正逐步成为推动我国信息技术自主可控、安全可靠的核心力量。信创产业不仅关乎国家信息安全,也是数字经济高质量发展的关键支撑。本文将深入探讨信创国产系统中的10个关键厂商及其技术生态,分析它们在信创浪...
项目管理流程   0  
  在探讨项目管理的广阔领域中,成功并非偶然,而是精心策划、高效执行与持续优化的结果。项目管理的成功之道,可以从明确的目标设定与规划、高效的团队协作与沟通、以及灵活的风险管理与适应变化这三个核心方面进行深入解析。每个方面都是项目成功的基石,它们相互交织,共同支撑起项目的顺利推进与最终成就。明确的目标设定与规划项目管理的首要...
建筑工程项目管理规范   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用