문제

Is there any way to check every element of a list comprehension in a clean and elegant way?

For example, if I have some db result which may or may not have a 'loc' attribute, is there any way to have the following code run without crashing?

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]

If there is any way to fill these fields in either as None or the empty string or anything, that would be much very nice. Python tends to be a magical thing, so if any of you have sage advice it would be much appreciated.

도움이 되었습니까?

해결책 2

Try this:

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]

Or, in your query set a default value.

다른 팁

Clean and unified solution:

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

It's not pretty, but getattr() should work:

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
]

This will set the dict item with key "latitude" to obj.loc.lat (and so on) if it exists; if it doesn't (and even if obj.loc doesn't exist), it'll be set to None.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top