有了一些Ruby经验,我开始学习Python和地图列表转换技术(select / map / reduce)到Python。 假设我想要一个列表[0..99],方形偶数并总结它。
在Python中:
arr = range(100)
res = [x*x for x in arr if x % 2 == 0]
res = reduce(lambda x,y: x+y, res)
在Ruby中
(0..99)
.select {|num| num % 2 == 0}
.map {|num| num*num}
.inject {|sum, n| sum + n}
到目前为止,它在Python中看起来很好而且惯用。 现在,假设我想投入更多的映射/过滤,说在我对偶数进行平方后,我想将那些可被10整除,然后将它们除以100,然后选择奇数。
在Ruby中,它可以很好地扩展到:
(0..99)
.select {|num| num % 2 == 0}
.map {|num| num*num}
.select {|num| num % 10 == 0}
.map {|num| num / 100}
.select {|num| num % 2 != 0}
.inject {|sum, n| sum + n}
在Python中,代码变得如此:
arr = range(100)
res = [x*x for x in arr if x % 2 == 0]
res = [x for x in res if x % 100 == 0]
res = [x / 100 for x in res]
res = [x for x in res if x % 2 != 0]
res = reduce(lambda x,y: x+y, res)
感觉这里的Python代码不是惯用的而且效率不高(我可以嵌套它,但它会变得不可读)。 还可以轻松修改Ruby中的代码以进行惰性求值,我无法对Python代码进行说明。 我如何在Python中表达这个想法和一个易读且高效的代码?
答案 0 :(得分:2)
每个人对可读代码的定义都有所不同。就个人而言,我觉得这个相当可读(至少是一个单行)并减少了很多不必要的理解:
sum([(x*x) / 100 for x in range(100) if not x*x % 100 and (x*x) / 100 % 2])
你可以再清理一下:
f = lambda x: (x*x) / 100
sum([f(x) for x in range(100) if not x*x % 100 and f(x) % 2])
这可能比问题中的一种理解长约10个字符。将6行减少为2行,将4个列表理解减少为单一理解。