Несколько операторов if / elif в понимании списка Python - PullRequest
0 голосов
/ 27 мая 2020

Итак, я новичок в Python, и к одной концепции, к которой пришлось немного привыкнуть, является понимание списка. Я читал, что они могут улучшить скорость вычислений при правильном использовании и что о них нужно хорошо знать, если вы научитесь Python правильным путем.

Я пишу программу, которая реализует алгоритм агрегации частиц, который включает накопление до 10 ^ 6 частиц в растущем кластере. Я возвращаюсь к своему коду, чтобы оптимизировать производительность везде, где это возможно, и у меня есть следующая функция:

 def step_all_walkers(walkers): 
    updated_positions = []
    for walker in walkers: 
        decision = random.randint(1,4)
        if decision == 1: 
            updated_walker = (min(walker[0]+1, N-1), walker[1])
        elif decision == 2: 
            updated_walker = (max(walker[0]-1, 1), walker[1])
        elif decision == 3: 
            updated_walker = (walker[0], min(walker[1] + 1, N-1))
        elif decision == 4: 
            updated_walker = (walker[0], max(walker[1]-1, 1))

        updated_positions.append(updated_walker)

    return updated_positions 

Эта функция заставляет каждую частицу (или ходок, как я называю их в коде) сделать шаг единицы длины в случайном направлении, и предотвращает ускользание частиц от сетки N x N. Я замечаю, что создаю и возвращаю новый список updated_positions, и, поскольку этот список и список входных walker потенциально очень большие, то, что я как бы знаю о понимании списков, подсказывает мне, что сейчас самое подходящее время для его использования. . Однако в некоторых других сообщениях по этому вопросу, где нужно оценить только одно if / else, люди ответили, говоря, что просто используйте хороший старый мод для l oop.

Тогда у меня есть несколько вопросов:

1) Можно ли использовать несколько операторов if / elif в понимании списка?

2) Имеет ли смысл писать это для l oop как понимание списка? Есть ли в этом какие-то преимущества?

Моя основная цель, чтобы задать этот вопрос, состоит в том, чтобы создать больше интуиции, когда уместно понимание списка, а также посмотреть, можно ли с его помощью сделать эту функцию более эффективной.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Я бы для начала превратил это в справочный словарь, а затем вы могли бы рассмотреть понимание списка

decisions = {1: lambda walker: (min(walker[0]+1, N-1), walker[1])}
return [decisions[random.randint(1,4)](walker) for walker in walkers]
0 голосов
/ 27 мая 2020

Случай, когда составление списка не должно использоваться , - это когда logi c слишком сложен.

Циклы For проще, поскольку они позволяют:

  • Включая комментарии для объяснения кода.
  • Использование ключевых слов потока управления, таких как continue.
  • Отладка разделов более удобна с помощью операторов регистрации или утверждений.
  • Разрешить другие, чтобы легко увидеть сложность logi c путем сканирования строк

Однако, как предлагает Сайз, мы часто можем упростить logi c с помощью дополнительных структур данных и вспомогательных функций, чтобы позволить понимание списка.

понимание списка без операторов if / else (необходимость в logi c пропущена)

def step_all_walkers(walkers, N):
  def decision(walker):
    " Helper function for making a decisions "
    # Place decision choices into a data structure
    options = [
      lambda walker: (min(walker[0]+1, N-1), walker[1]),
      lambda walker: (max(walker[0]-1, 1), walker[1]),
      lambda walker: (walker[0], min(walker[1] + 1, N-1)),
      lambda walker: (walker[0], max(walker[1]-1, 1))]

    while True:
      n = random.randint(0, 3)  # use rather than (1, 4) to 
                                # provide proper index into options
      yield options[n](walker)

# Now, list comprehension is straight forward to follow
return [decision(walker) for walker in walkers]
...