2

リスト内包表記のすべての要素をクリーンでエレガントな方法でチェックする方法はありますか?

たとえば、'loc' 属性がある場合とない場合がある db の結果がある場合、クラッシュせずに次のコードを実行する方法はありますか?

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 は魔法のようなものになる傾向があるため、賢明なアドバイスがあれば、非常にありがたいです。

4

3 に答える 3

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
于 2013-08-17T08:27:08.513 に答える
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]

または、クエリでデフォルト値を設定します。

于 2013-08-17T07:53:32.750 に答える
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"これにより、キーがobj.loc.lat存在する場合は (など)の dict 項目が設定されます。存在しない場合 (obj.loc存在しない場合でも)、 に設定されNoneます。

于 2013-08-17T08:00:39.350 に答える