Отличия циклов и генераторов списков
Есть список вложенных словарей, в которые также вложены списки и словари. Из него, с помощью индексов и циклов нужно сформировать новый список. И это довольно просто сделать циклом, но мне интересно разобраться в генераторах, коль скоро они являются одной из фишек Python. Собственно вопрос в следующем, почему при проходе по списку стандартным циклом:
girls_drivers = []
for user in users:
friends = user.get('friends', [])
for friend in friends:
if friend['sex'] == 'F' and friend.get('cars'):
girls_drivers.append(friend['name'])
все работает нормально, но если я пытаюсь создать такой же список с помощью генератора - он начинает ругаться, что нужен индекс. И без индексов (там, где в коде "-1") не работает.
girls_drivers = [friend.get('friends')[-1].get('name') for friend in users
if 'friends' in friend and friend['friends'][-1]['sex'] == 'F' and 'cars' in friend['friends'][-1]]
Каким образом можно сделать из цикла выше генератор, чтобы он перебирал все элементы списка, а не только -1 элемент списка? И почему генератору нужны индексы элементов, а циклу нет?
Ответы (1 шт):
Я не понял, зачем у вас там индексация [-1] вообще. Ваш стандартный цикл аналогичен следующему списковому сокращению:
girls_drivers = [friend['name'] for user in users for friend in user.get('friends', [])
if friend['sex'] == 'F' and friend.get('cars')]
А если хотите генератор, то просто замените квадратные скобки girls_drivers = [ ... ] на круглые girls_drivers = ( ... ) это и всё отличие в синтаксисе между списочным сокращением и генератором.
P.S. Рецепт написания списочного сокращения из обычной формы записи кода:
- сразу за открывающей скобкой
[пишем аргумент функцииlist.append- ведь это именно то, что будет добавляться в список - циклы
forидут точно в том же порядке, что и в обычной записи, просто в одну строку и без: - перед закрывающей скобкой
]идётif, отбирающий элементы для добавления в список