python列表推导的嵌套多少合适?

时间:2013-04-03 12:06:38

标签: python list nested list-comprehension readable

我是一个相对蟒蛇初学者,现在对语言相当熟悉,但仍然在努力解决什么是“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

1 个答案:

答案 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>