2013-08-17 46 views
2

有什麼辦法以乾淨優雅的方式檢查列表理解的每個元素?乾淨的解決方案,爲Python列表解析中的缺失值

例如,如果我有一些可能或可能不具有'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往往是一件神奇的事情,所以如果你們中任何一個人都有聖人的建議,我們將非常感激。

回答

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] 

或者,在查詢中設置的默認值。

+0

這看起來比我的好。但是,讓地理位置位於最高分數列表中的人可能會幫助某人銷售更多地理定位廣告。 – Paul

+1

如果'obj.loc'不存在,這將不起作用。 –

+0

'getattr(obj.loc,'la​​t','')'工作。和@ZeroPiraeus,如果obj.loc不存在,只會嘗試在沒有任何內容的情況下調用'lat',這將返回默認值。謝謝大家的快速回答 –

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(依此類推),如果存在的話;如果沒有(並且即使obj.loc不存在),它將被設置爲None

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 
相關問題