【问题标题】:Insert list of attributes into list of objects in python将属性列表插入到python中的对象列表中
【发布时间】:2013-07-02 07:55:59
【问题描述】:

如何将包含属性值的列表(或 numpy 数组)插入到对象列表中(如下所示)?

class myClass(object):
    def __init__(self, attr):
        self.attr = attr
        self.other = None

objs = []
for i in range(10):
        objs.append(myClass(i))

attrs = [o.attr for o in objs]
print attrs
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[o.attr for o in objs] = range(10)
#SyntaxError: can't assign to list comprehension

这是Extract list of attributes from list of objects in python的逆问题。

【问题讨论】:

  • 请注意,您的对象创建也可以是一个列表组合:objs = [myClass(i) for i in range(10)]

标签: python list numpy


【解决方案1】:

您也可以在列表理解中使用obj.__setattr__()

[o.__setattr__('attr',v) for o,v in zip(objs,range(10)[::-1])]
print [o.attr for o in objs]
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

【讨论】:

  • -1 - 这是重新实现轮子(setattr() 存在),它使用列表推导来处理副作用,这是一个糟糕的主意。
  • 完全正确,我太草率了。这是使用内置 __setattr__ 方法的稍微不那么愚蠢的答案,尽管如果是我,我仍然会使用 John Zwinck 的方法。
  • 为什么要直接访问魔术方法?这仍然使用列表推导来处理副作用。
  • 我知道这很丑,只是指出如果你不介意招致其他 Python 程序员的仇恨,它实际上可以在列表理解中完成 :)
  • @Lattyware 有趣地看到 pythonic 对“副作用的比较列表”的厌恶,来自 Matlab 我会假设如果使用单个代码行来获取数据,则单个代码行可以用于设置数据...我想这可以解释它stackoverflow.com/questions/5753597/…
【解决方案2】:

我会这样做:

for i, o in enumerate(objs):
    o.attr = i

enumerate(objs) 有点像zip(range(len(objs)), objs),所以如果你真的想从另一个序列中取值,你可以:

for i, o in zip(sequence, objs):
    o.attr = i

为了提高效率,您也可以在那里使用 itertools.izip。

【讨论】:

  • +1,我正要建议您可能想提供一个更通用的解决方案,但它出现了。作为对风格的一个小小的说明,就个人而言,我会让sequenceobj 在对zip() 的调用中以相反的方式出现(并且自然地将i, o 交换为o, i 以保持功能相同)因为它将反映对象在代码中的使用顺序。不重要或更改任何功能,但我认为它更具可读性。
  • @Lattyware:在实践中,我也会交换 zip 中的顺序,但在这里我保持不变,以避免分散 zip 与 range 等效于枚举这一点。
猜你喜欢
  • 2014-10-24
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2016-04-26
  • 2022-06-15
相关资源
最近更新 更多