清除python列表推导中缺失值的解决方案

时间:2013-08-17 07:43:55

标签: python list-comprehension dictionary-comprehension

有没有办法以干净优雅的方式检查列表理解的每个元素?

例如,如果我有一些db结果,可能有也可能没有' 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往往是一个神奇的东西,所以如果你们中的任何人都有圣人的建议,那将非常感激。

3 个答案:

答案 0 :(得分:3)

清洁统一的解决方案:

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

答案 1 :(得分:1)

试试这个:

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]

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

答案 2 :(得分:1)

它不漂亮,但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