Python - 简短的语法和列表理解和迭代

时间:2014-07-25 06:32:31

标签: python list iteration list-comprehension

我非常喜欢Python的列表理解,我认为它实际上比常规迭代更容易阅读。

我正在编写一个在**kwargs中有可选参数的构造函数,可用于设置类'并且我想把它写成列表理解,但是有一个实际上没有做任何事情的清单似乎没有意义。考虑一下:

class Book(object):
    attrs = ('id', 'title', 'authors',...)
    def __init__(self, *args, **kwargs):
        [setattr(self, attr, kwargs.get(attr) 
              for attr in O.attrs if kwargs.get(attr)]

虽然语法看起来很好,但我认为这是错误的编码,因为你已经创建了一个

列表
[None, None, None...]

那只是坐在那里。是的,我知道它是在构造函数运行后收集的,但我仍然不喜欢它。如果我读了某人的代码,那我就不会感到沮丧。

是否有更好的方法可以完成迭代,如同列表理解一样干净,但不会创建无用的对象

编辑:

响应使用循环

class Book(object):
    attrs = ('id', 'title', 'authors',...)
    def __init__(self, *args, **kwargs):
         for attr in attrs:
             if kwargs.get(attr):
                 setattr(self, attr, kwargs.get(attr)

这是你们的意思吗?如果没有,那么写一个更好的方法呢?

2 个答案:

答案 0 :(得分:3)

您可以使用生成器表达式直接更新instance __dict__ attribute而不是列表解析:

class Book(object):
    attrs = ('id', 'title', 'authors',...)
    def __init__(self, *args, **kwargs):
        self.__dict__.update(
            (attr, kwargs[k]) for k in kwargs.viewkeys() & self.attrs)

这也使用dictionary views;在Python 3中,只需使用kwargs.keys()而不是kwargs.viewkeys()。字典视图作为一个集合; & self.attrs表达式生成kwargs的键与属性列表之间的交集。

生成器表达式生成(key, value)对,dict.update() method的两个可接受输入之一。

更新self.__dict__ 就好了; Python 2.7标准库在7个不同的位置使用这种技术,加上大约30个其他的突变案例。请注意,如果您使用描述符(@property和/或其他自定义描述符),那么访问self.__dict__会绕过这些描述符。

关于副作用的列表理解:只是不要。你确实在浪费周期创建一个立即丢弃的列表对象,混淆了对列表理解 的期望。

您还可以在常规setattr()循环中将其与显式for次调用结合使用:

for attr in kwargs.viewkeys() & self.attrs:
    setattr(self, attr, kwargs[attr])

答案 1 :(得分:2)

怎么样:

for attr in [a for a in attrs if a in kwargs]:
    setattr(self, attr, kwargs[attr])

这相当简单和甜蜜......

或者克里斯建议:

for attr in (a for a in attrs if a in kwargs):

会更好。 (生成器而不是列表)