【问题标题】:Avoid multiple similar lines in python避免在python中出现多个相似的行
【发布时间】:2013-04-08 12:23:15
【问题描述】:

我的问题是关于编码风格:当我想将一个过程应用于多个变量时,例如:

from pylab import vstack     # the function to apply to many variables
v1 = range(5)      # some dummy variables
v2 = range(9)
...
v20 = range(8)

# now, I want to apply a function to all variables that changes them!
v1 = vstack(v1)   # I really do not need the "old" v1 anymore
v2 = vstack(v2)
...
v20 = vstack(v20)

这是 20 行几乎相同的代码。 有没有办法用更少的行编写转换 (vx = vstack(vx))?

将它们放入可迭代对象中不起作用:

all_v = [v1, v2, v3, .... , v20]
for v in all_v:
    v = vstack(v)

type (v1) # -> v1: <type: list>

【问题讨论】:

    标签: python coding-style


    【解决方案1】:

    您是否真的需要一开始就将它们放在单独的变量中?这通常是一种代码气味。如果名称很重要,我会将它们保存在一个列表中,或者一个字典中,并更新:

    my_data = {}
    my_data['v1'] = range(5)
    my_data['v2'] = range(9)
    ...etc...
    
    my_data = {k: vstack(v) for k, v in my_data.iteritems()}
    

    【讨论】:

    • 您“捆绑”变量的提议当然有效,我想我会这样做。但是,我想知道(好奇)我的问题是否有解决方案?
    • 您可以通过更新locals() 字典来实现。但是,这真的不推荐。 locals().update({k: v for k, v in locals().items() if k in ['v1', 'v2' ... ]})
    【解决方案2】:
    from pylab import vstack
    parameters = (5, 9, ..., 8)
    
    v = [vstack(range(p)) for p in parameters]
    

    这将在 parameters 元组上运行列表推导,其中包含您的 range 函数的参数。对于该元组中的每个参数,range 函数的结果将传递给vstack 函数。结果收集在一个列表中。

    所以v[0]对应参数值parameters[0]等的结果。

    在您的代码中它不起作用,因为您在循环中本地覆盖了 v 变量。这不会更改原始列表中的项目。如果你想从这些结果中创建一个(新的)列表,你可以使用list.append

    all_v = [v1, v2, v3, .... , v20]
    new_v = []
    for v in all_v:
        new_v.append(vstack(v))
    

    【讨论】:

    • 谢谢!但是,对于 practical 部分,我认为 Daniel 的解决方案很好。不过,我有兴趣(纯粹是好奇)知道是否有解决我最初问题的方法。
    • @user2055010 这不是在最后一段和代码摘录中回答的吗?这是您最初尝试过的解决方案,可以正常工作。
    • 那么,我没有旧变量名的新值。 (Daniel 提议更新locals() 字典——这正是我想要的。)
    • @user2055010 你should never 直接更新这些值。它是非常具体的实现,不能保证工作。更改存储原始值的方式。
    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 2013-12-21
    相关资源
    最近更新 更多