Выражение понимания списка - PullRequest
0 голосов
/ 05 ноября 2011

У меня есть функция, которая выглядит так:

  def roulette(self):
    sum = 0
    lst = []
    for x in self.drinkList:
        sum += x.fitness
        lst.append(sum)
    return lst

Может ли оно быть заменено выражением понимания списка или чем-то более эффективным, чем для цикла?

PS: это означает, что если я делаю random.randrange (0), то возникает исключение ValueError: пустой диапазон для randrange () Есть ли способ избежать этого без использования if test?

Ответы [ 4 ]

4 голосов
/ 05 ноября 2011

На самом деле можно «заглянуть» в список, построенный в понимании списка.самый внешний список имеет имя _[1], которое, конечно, не является допустимым идентификатором Python, поэтому к нему нужно обращаться по-другому:

def roulette(self):
    return [drink.fitness + (locals()['_[1]'][-1] if locals()['_[1]'] else 0) 
            for drink 
            in self.drinkList]

Но только потому, что вы можете ,не означает, что вы должны ;продолжайте свой цикл for, он выглядит точно так же, как и делает, а также не использует недокументированную функцию Python.

1 голос
/ 05 ноября 2011

Ваша функция 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, но вызовы функций медленные.(Подстановка понимания списка для выражения генератора может ускорить процесс за счет памяти.)

0 голосов
/ 06 ноября 2011

Я не знаю, является ли это более эффективным, но у него есть понимание списка и меньше строк:

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:]
0 голосов
/ 05 ноября 2011
[sum(x.fitness for x in self.drinklist[:i+1]) for i in range(len(self.drinklist))]

Но это будет O (n ^ 2), а у вас O (n).

...