Я делаю генерацию кода в Jinja2, и я часто хочу перебирать два списка вместе (т.е. имена и типы переменных), есть ли простой способ сделать это или мне нужно просто передать список с предварительным сжатием? Мне не удалось найти такую функцию в docs или googling.
Zip (list1, list2) в Jinja2?
Ответ 1
Измените jinja2.Environment глобальное пространство имен, если вы считаете нужным.
import jinja2
env = jinja2.Environment()
env.globals.update(zip=zip)
# use env to load template(s)
Это может быть полезно для разделения логики представления (шаблона) из логики приложения, но также позволяет обратное. # разделение конфликтов
Ответ 2
Я не думаю, что шаблоны языков позволяют делать zip из двух контейнеров для цикла. Вот аналогичный вопрос для django, а jinja templating очень близок к django's.
У вас была бы предварительная сборка сжатого контейнера и переход к вашему шаблону.
>> for i,j in zip(range(10),range(20,30)):
... print i,j
...
Является эквивалентным
>>> [(i,j) for i,j in zip(range(10),range(20,30))]
Ответ 3
Поскольку вы не упомянули, используете ли вы Flask или нет, я решил, что добавлю свои выводы.
Для использования render_template()
создайте фильтр zip с помощью функции zip()
в среде Jinja2, используемой Flask.
app = Flask(__name__)
...
app.jinja_env.filters['zip'] = zip
Чтобы использовать это в шаблоне, сделайте следующее:
{% for value1, value2 in iterable1|zip(iterable2) %}
{{ value1 }} is paired with {{ value2 }}
{% endfor %}
Имейте в виду, что строки являются итерируемыми Jinja2, поэтому, если вы попытаетесь застегнуть строки, вы получите сумасшедшие вещи. Чтобы убедиться, что вы хотите сделать zip, итерабельно, а не строка, выполните следующие действия:
{% if iterable1 is iterable and iterable1 is not string
and iterable2 is iterable and iterable2 is not string %}
{% for value1, value2 in iterable1|zip(iterable2) %}
{{ value1 }} is paired with {{ value2 }}
{% endfor %}
{% else %}
{{ iterable1 }} is paired with {{ iterable2 }}
{% endif %}