我有一个看起来像这样的功能:
def roulette(self):
sum = 0
lst = []
for x in self.drinkList:
sum += x.fitness
lst.append(sum)
return lst
是否可以用列表推导表达式替换或者比for循环更有效的东西?
PS:如果我执行random.randrange(0),它会引发异常ValueError:randrange()的空范围。有没有办法在不使用if test的情况下避免它?
答案 0 :(得分:4)
实际上可以“查看”列表理解中构建的列表。最外层列表的名称为_[1]
,当然这不是有效的python标识符,因此必须以其他方式访问它:
def roulette(self):
return [drink.fitness + (locals()['_[1]'][-1] if locals()['_[1]'] else 0)
for drink
in self.drinkList]
但仅仅因为你可以并不意味着你应该;使用for
循环,它看起来就像它的功能一样,也不依赖于未记录的python功能。
答案 1 :(得分:1)
您的roulette
函数正在计算列表的部分总和
x.fitness
元素。
您可以通过定义闭包并使用map
来获得相同的结果
生成器表达式。
sum = 0
def partial_sum(x):
sum += x
return sum
lst = map(partial_sum, (x.fitness for x in self.drinkList))
这肯定不太可读而不是for
循环;它可能会更快
但你必须进行实验:map
通常比for
快,
但函数调用很慢。 (代替列表理解
生成器表达式可能会以牺牲速度为代价加快速度
存储器。)
答案 2 :(得分:0)
[sum(x.fitness for x in self.drinklist[:i+1]) for i in range(len(self.drinklist))]
但这是O(n ^ 2),而你的是O(n)。
答案 3 :(得分:-1)
我不知道它是否更有效率,但这有一个列表理解和更少的行:
def roulette(self):
lst = [self.drinkList.pop(0).fitness]
[ lst.append(x.fitness + lst[-1]) for x in self.drinkList]
return lst
由于没有授权我修改列表 self.drinkList ,我重写:
def roulette(self):
lst = [0]
[ lst.append(x.fitness + lst[-1]) for x in self.drinkList]
return lst[1:]