#python #list-comprehension
#python #понимание списка
Вопрос:
Как бы я мог более эффективно выполнять следующие действия, не повторяя дважды сжатый список:
x = [(item1['a'], item2) for item1, item2 in zip(foo, bar)]
y = [item2.replace(item1['b'], '') for item1, item2 in zip(foo, bar)]
Комментарии:
1. Если я чего-то не упускаю, просто не используйте понимание списка. Инициализируйте x и y, затем выполните цикл for с zip. Внутри одного-единственного цикла for добавляйте как к x, так и к y.
Ответ №1:
Немного менее Pythonic:
x = []
y = []
for item1,item2 in zip(foo,bar):
x.append((item1['a'],item2))
y.append(item2.replace(item1['b'],''))
Комментарии:
1. почему это менее pythonic? 🙂
2. @Tomerikoo: это всего лишь мое мнение 😉
3. Я просто думаю, что люди склонны зацикливаться на составлениях списков, и иногда (как в этом случае) старый добрый цикл больше похож на pythonic (простой лучше, чем сложный и все такое …)
Ответ №2:
В общем, вы можете использовать выражение генератора для вывода нескольких значений в виде кортежей, а затем zip
преобразовать последовательность кортежей в отдельные последовательности, чтобы вы могли распаковать их в отдельные переменные.
Поэтому вместо, например:
x = [i 1 for i in lst]
y = [i 2 for i in lst]
Вы можете сделать:
x, y = zip(*((i 1, i 2) for i in lst))
Однако в этом случае x
и y
станут кортежами, поэтому, если вам нужно, чтобы x
и y
были настоящими списками, вместо этого вы можете map
последовательность вывода в list
конструктор:
x, y = map(list, zip(*((i 1, i 2) for i in lst)))
Таким образом, утверждения в вашем вопросе могут быть переписаны как:
x, y = map(list, zip(*(((item1['a'], item2), item2.replace(item1['b'], '')) for item1, item2 in zip(foo, bar))))
Комментарии:
1. Они выводятся в виде кортежей, а не списков.