我是一个相对蟒蛇初学者,现在对语言相当熟悉,但仍然在努力解决什么是“pythonic”而不是。我想知道人们对这个问题的想法是什么。
例如,使用这行代码计算从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
答案 0 :(得分: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)
似乎是一种更合适的计算方法。我实际上创建的更少的对象比你的代码更少,因为我没有两个列表,我没有充分的理由,而你的代码为中间计算制作了两个列表,然后抛弃它们。 / p>