2013-04-03 31 views
-1

我是一個相對的Python初學者,現在對這門語言很滿意,但仍然在努力解決什麼是「pythonic」而不是問題。我想知道人們對這個問題的想法是什麼。python列表解析的嵌套是多少?

例如,走這條線的代碼,用於計算每星期的平均成本從peewee數據庫提取租賃的性質:

 
    rental_avg_costperweek = sum([calcCostPerWeek(rental.price, rental.rental_freq) for rental in 
           [LLSRental.select(LLSRental.id == this_id) for this_id in closest_rental_ids]]) \ 
          /len(closest_rental_ids) 

它使用嵌套列表解析,這可能是令人困惑的。

我也可以堅持內理解成一個臨時變量:

 
    closest_rental_records = [LLSRental.select(LLSRental.id == this_id) for this_id in closest_rental_ids] 
    rental_avg_costperweek = sum([calcCostPerWeek(rental.price, rental.rental_freq) for rental in closest_rental_records]) \ 
          /len(closest_rental_ids) 

這可能是(略)更容易閱讀,但作爲一名前的C++程序員,我很反感純粹創建臨時變量爲了可讀性,因爲它使命名空間混亂並且可能爲垃圾收集器做出更多工作。

此外,我認爲如果讀者不明白該變量是純粹的臨時變量,它可能會使代碼更混亂,如果有很多這樣的變量。

因此,我傾向於第一個選擇超過第二個選項,儘管「平坦度比嵌套更好」的指導意見......但是,你們蟒蛇老兵們的想法是什麼?

謝謝!
gs。

+5

「我厭惡爲了可讀性而創建臨時變量」 - 你應該克服這個問題。它不會爲GC工作更多,因爲如果創建對象,則無論如何都需要收集它。如果你真的想確保臨時變量是立即收集的,那麼會有'del',這會減少ref-count並使其可用於收集。 – mgilson

+1

如果您需要擔心混淆本地名稱空間,您的函數可能會做太多工作。 –

+0

這個問題不是建設性的,沒有正確的答案。這裏唯一的東西是偏好和要求。你可以使用[PEP8](http://www.python.org/dev/peps/pep-0008/),或者你可能會被迫在你的工作或教育地點採用某種風格......否則......偏好。 –

回答

1

我認爲兩者都是錯誤的。看起來你正在做內部理解,因爲你想避免重新計算LLSRental.select()。你應該很少需要內在​​的理解,因爲你可以嵌套它們,就像

all_the_inputs = [ process_value(x) for y in all_the_stuff for x in y ] 

什麼的。 This is a nice but short post這很好的解釋了這一點。

無論如何。類似於

rental_avg_costperweek = 0 
for this_id in closest_rental_ids: 
    rental = LLSRental.select(LLSRental.id == this_id) 
    rental_avg_costperweek += calcCostPerWeek(rental.price, rental.rental_freq) 
rental_avg_costperweek /= len(closest_rental_ids) 

似乎是一種更合適的計算方法。實際上我創建的對象數量比你的代碼少,因爲我沒有兩個我沒有理由的列表,而你的代碼爲中間計算製作了兩個列表,然後拋出它們。

+0

感謝您的回答。感謝我的代碼創建不必要的對象,也是列表理解的雙循環形式,這非常有用。我認爲我錯誤地將列表推導用作循環來創建簡潔的代碼,事實上,這樣做實際上可能會更加低效,正如您指出的那樣。 –