2013-04-03 36 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

感谢您的回答。感谢我的代码创建不必要的对象,也是列表理解的双循环形式,这非常有用。我认为我错误地将列表推导用作循环来创建简洁的代码,事实上,这样做实际上可能会更加低效,正如您指出的那样。 –