列表理解表达式

时间:2011-11-05 16:18:46

标签: python list-comprehension

我有一个看起来像这样的功能:

  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的情况下避免它?

4 个答案:

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