На этом шаге мы рассмотрим альтернативные способы работы со списками.
На предыдущем шаге мы изменяли элементы списка следующим образом:
arr = [1, 2, 3, 4] for i in range(len(arr)): arr[i] *= 2 print(arr) # Результат выполнения: [2, 4, 6, 8]
С помощью генераторов списков тот же самый код можно записать более компактно. Помимо компактного отображения, польза здесь также и в том, что генераторы списков работают быстрее цикла for. Однако вместо изменения исходного списка возвращается новый список:
arr = [1, 2, 3, 4] arr = [i * 2 for i in arr] print (arr) # Результат выполнения: [2, 4, 6, 8]
Как видно из примера, мы поместили цикл for внутри квадратных скобок, а также изменили порядок следования параметров, - инструкция, выполняемая внутри цикла, находится перед циклом. Обратите внимание и на то, что выражение внутри цикла не содержит оператора присваивания, - на каждой итерации цикла будет генерироваться новый элемент, которому неявным образом присваивается результат выполнения выражения внутри цикла. В итоге будет создан новый список, содержащий измененные значения элементов исходного списка.
Генераторы списков могут иметь сложную структуру. Например, состоять из нескольких вложенных циклов for и (или) содержать оператор ветвления if после цикла. Для примера получим четные элементы списка и умножим их на 10:
arr = [1, 2, 3, 4] arr = [i * 10 for i in arr if i % 2 == 0] print(arr) # Результат выполнения: [20, 40]
Последовательность выполнения этого кода эквивалентна последовательности выполнения следующего кода:
arr = [] for i in [1, 2, 3, 4] : if i % 2 == 0: # Если число четное arr.append(i * 10) # Добавляем элемент print(arr) # Результат выполнения: [20, 40]
Усложним наш пример. Получим четные элементы вложенного списка и умножим их на 10:
arr = [[1, 2], [3, 4], [5, 6]] arr = [j * 10 for i in arr for j in i if j % 2 == 0 print(arr) # Результат выполнения: [20, 40, 60]
Последовательность выполнения этого кода эквивалентна последовательности выполнения следующего кода:
arr = [] for i in [[1, 2], [3, 4], [5, 6]]: for j in i: if j % 2 == 0: # Если число четное arr.append(j * 10) # Добавляем элемент print(arr) # Результат выполнения: [20, 40, 60]
Если выражение разместить внутри не квадратных, а круглых скобок, то будет возвращаться не список, а итератор. Такие конструкции называются выражениями-генераторами. В качестве примера просуммируем четные числа в списке:
>>> arr = [1, 4, 12, 45, 10] >>> sum((i for i in arr if i % 2 == 0)) 26
Со следующего шага мы начнем рассматривать функции map(), zip(), filter() и reduce().