【问题标题】:Clean solution for missing values in python list comprehensionspython列表推导中缺失值的干净解决方案
【发布时间】:2013-08-19 15:11:29
【问题描述】:

有没有什么方法可以简洁优雅地检查列表推导的每个元素?

例如,如果我有一些可能有也可能没有'loc'属性的数据库结果,有没有办法让以下代码运行而不会崩溃?

db_objs    = SQL("query")
top_scores = [{"name":obj.name, "score":obj.score, "latitude":obj.loc.lat, "longitude":obj.loc.lon} for obj in db_objs]

如果有任何方法可以将这些字段填充为 None 或空字符串或任何内容,那将非常好。 Python 往往是一个神奇的东西,所以如果你们有任何明智的建议,将不胜感激。

【问题讨论】:

    标签: python list-comprehension dictionary-comprehension


    【解决方案1】:

    干净统一的解决方案:

    from operator import attrgetter as _attrgetter
    
    def attrgetter(attrname, default=None):
        getter = _attrgetter(attrname)
        def wrapped(obj):
            try:
                return getter(obj)
            except AttributeError:
                return default
    
        return wrapped
    
    GETTER_MAP =  {
        "name":attrgetter('name'),
        "score":attrgetter('score'),
        "latitude":attrgetter('loc.lat'),
        "longitude":attrgetter('loc.lon'),
        }
    
    def getdict(obj):
        return dict(((k,v(obj)) for (k,v) in GETTER_MAP.items()))
    
    if __name__ == "__main__":
        db_objs    = SQL("query")
        top_scores = [getdict(obj) for obj in db_objs]
        print top_scores
    

    【讨论】:

      【解决方案2】:

      它不漂亮,但getattr() 应该可以工作:

      top_scores = [
          {
              "name": obj.name,
              "score": obj.score,
              "latitude": getattr(getattr(obj, "loc", None), "lat", None),
              "longitude": getattr(getattr(obj, "loc", None), "lon", None),
          }
          for obj in db_objs
      ]
      

      这会将带有键"latitude" 的dict 项设置为obj.loc.lat(以此类推)(如果存在);如果不存在(即使obj.loc 不存在),它将被设置为None

      【讨论】:

        【解决方案3】:

        试试这个:

        top_scores = [{"name":obj.name,
                       "score":obj.score,
                       "latitude": obj.loc.lat if hasattr(obj.loc, lat) else 0
                       "longitude":obj.loc.lon if hasattr(obj.loc, lon) else 0}
                       for obj in db_objs]
        

        或者,在您的查询中设置一个默认值。

        【讨论】:

        • 这看起来比我的好。但是,让人们在地理位置上排名靠前可能会帮助某人销售更多的地理位置定位广告。
        • getattr(obj.loc,'lat','') 也有效。和@ZeroPiraeus,如果 obj.loc 不存在,它只会尝试调用 'lat' 什么都不会返回默认值。谢谢大家的快速解答
        • @JoeDelgado 除非您的 obj 特别奇怪,否则这不是真的:在 Python 解释器中尝试 class Foo: pass 然后 obj = Foo() 然后 obj.loc.lat if hasattr(obj.loc, lat) else 0。你会得到一个AttributeError
        猜你喜欢
        • 1970-01-01
        • 2021-03-20
        • 2016-11-26
        • 2010-09-18
        • 2019-07-02
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 2011-07-12
        相关资源
        最近更新 更多