【问题标题】:List comprehension with two outputs具有两个输出的列表理解
【发布时间】:2020-02-12 17:05:12
【问题描述】:

我正在尝试优化这段代码:

num = 10
for j in xrange(0,num):
  u[j],v[j] = rk4(du,dv,t,dt,u[j],v[j])

其中 u 和 v 是输入数组,rk4() 为两个输入值返回两个值。使用列表理解我会做这样的事情:

u,v=[rk4(du,dv,t,dt,u[j],v[j])) for j in range(0,num)]

列表理解有效。但是输出格式不同。是否可以使用列表推导来优化这种操作?

编辑:所需的输出将是两个数组/列表形式的

u,v = [u1,u2,u3,....],[v1,v2,v3,...]

我得到的是以下形式:

[(u1,v1),(u2,v2),(u3,v3),...]

【问题讨论】:

  • 请添加输出有何不同,您的预期输出是什么
  • 你的列表理解不是优化。
  • 为什么?实际上,我已经阅读了一些博客文章,建议将其用作某种性能优化,并且我的代码很慢,所以我正在尝试对此做一些事情。
  • @gumpel 那些博客文章是错误的。列表推导式仅比等效的 for 循环略微快,并且这种优势会缩小每次迭代完成的工作量。
  • 首选列表推导的主要原因是代码更简洁。您可以只写入列表中的内容,而不是向列表中写入append 的命令。当您进行数值计算时,性能差异几乎可以忽略不计(我假设 Runge-Kutta)。

标签: python list-comprehension


【解决方案1】:

您似乎想将一个对序列转换为两个序列。 Python 中有一个标准的习惯用法是使用 zip 函数和参数解包来做到这一点:

>>> seq_of_pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> u, v = zip(*seq_of_pairs)
>>> u
('a', 'b', 'c', 'd')
>>> v
(1, 2, 3, 4)

因此,您可以使用列表推导(或生成器表达式)使用zip 生成对序列,然后使用该技巧提取两个序列:

result = [ rk4(..., ui, vi) for ui, vi in zip(u, v) ]
u, v = zip(*result)

如果您需要它们是列表而不是元组,您可以使用u, v = map(list, zip(*result))

【讨论】:

    猜你喜欢
    • 2021-10-19
    • 2016-01-19
    • 2019-06-07
    • 2019-08-05
    • 2013-05-10
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多