【问题标题】:append in a list in Python using result value or a function使用结果值或函数附加到 Python 中的列表中
【发布时间】:2013-03-10 17:49:35
【问题描述】:

从性能和编码风格的角度来看,这两种方法是否等效?

def foo(n):
    return n*2

# case 1 with ".append(function())"

mylist = [1,2,3,4,5,6,7,8,9,10]
result = list()
for l in mylist:
    result.append(foo(l))

# case 2 ".append(result)"

mylist = [1,2,3,4,5,6,7,8,9,10]
result = list()
for l in mylist:
    r = foo(l)
    result.append(r)

【问题讨论】:

  • 解决方案1更具可读性和紧凑性,但基本上没人关心。
  • 性能 = ,编码 != 首先更好,但 Python 支持更好的方法..

标签: python optimization coding-style


【解决方案1】:

您的方法或多或少是等效的;选项 2 做了一点更多的工作;它必须对临时变量进行额外的存储和名称查找。实际上,差异很小,您应该更关注代码的可读性而不是过早的优化。

对于您的特定示例,您最好使用列表理解:

result = [foo(l) for l in mylist]

列表推导式在 C 代码中构造列表,不必在每次循环迭代时查找 .append() 方法。

【讨论】:

  • 谢谢 Martijn。我的问题是理论多于实践。通常我使用第一种情况。
  • 很抱歉提出了额外的问题,但为什么 C 或 C++ 比 Python 等其他语言更快?
  • @Gianni:因为 C 和 C++ 可以编译为机器代码,所以在代码结构和类型系统的刚性方面做出了非常不同的决定。最后,您在哪些方面更有效率,是什么让您更快地创建解决方案?
  • @Gianni:鉴于此,this answer 关于 Google 为什么使用 Python 很有趣。
  • 看看numpyscipy,或者pandas;所有使特定分析工作更快的库,同时仍为您提供 Python 的强大功能来控制这一切。
【解决方案2】:

我认为它们是相同的,但最好的选择是 map(foo, mylist) - 即使从性能的角度来看,append 也会导致列表调整大小,这需要额外的时间

【讨论】:

  • 在 python 3 中,map() 将返回一个迭代器;如果您一直需要一个列表,列表理解案例仍然可以胜过list(map(..))
  • 关于 Python 3 的这一点你是对的。我认为 list(imap(..))map(..) 之间的性能差异很难注意到,特别是对于比某些(不大)X 更长的列表。另外对于 Python 2.x 的优势可能在 map 方面
  • 是的,对于 OP 中的特定示例输入,Python 2 中的 map()快。但是,对于 long 列表,列表推导式会胜出,因为它可以更有效地构建结果列表。
  • 您确定该列表的构建方式与列表理解不同吗?直观地说,这应该以完全相同的方式工作 - 理解被转换为生成器,它是新列表的基础......
  • 列表推导确实使用生成器,实际上。 map() 和列表推导式都有专门的 C 代码来构建列表。我使用timeit 模块来比较两种方法的性能。
【解决方案3】:

仅删除临时分配可能会获得一些性能提升,但请记住,过早优化是邪恶的,微优化不值得努力

当然还有更好的方法,例如

列表理解

mylist = [1,2,3,4,5,6,7,8,9,10]
result = [n*2 for n in mylist]

【讨论】:

  • 谢谢阿比吉特。为什么“过早的优化是邪恶的”?我到处读这句话!!!
  • @Gianni 你应该首先担心代码的清晰度和健壮性
【解决方案4】:
result = [foo(i) for i in mylist]

是你想要的。

【讨论】:

    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 2018-08-15
    • 2022-10-23
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多