zip(list1, list2) in Jinja2?

PythonCode GenerationJinja2

Python Problem Overview


I'm doing code generation in Jinja2 and I frequently want to iterate through two lists together (i.e. variables names and types), is there a simple way to do this or do I need to just pass a pre-zipped list? I was unable to find such a function in the docs or googling.

Python Solutions


Solution 1 - Python

Modify the jinja2.Environment global namespace itself if you see fit.

import jinja2
env = jinja2.Environment()
env.globals.update(zip=zip)
# use env to load template(s)

This may be helpful in separating view (template) logic from application logic, but it enables the reverse as well. #separationofconcerns

Solution 2 - Python

Since you didn't mention if you are using Flask or not I figured I'd add my findings.

To be used by a render_template() create the 'zip' filter using the zip() function in the Jinja2 environment used by Flask.

app = Flask(__name__)
...
app.jinja_env.filters['zip'] = zip

To use this within a template do it like this:

{% for value1, value2 in iterable1|zip(iterable2) %}
    {{ value1 }} is paired with {{ value2 }}
{% endfor %}

Keep in mind that strings are iterable Jinja2 so if you try to zip to strings you'll get some crazy stuff. To make sure what you want to zip is iterable and not a string do this:

{%  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 %}

Solution 3 - Python

For Flask, you can pass the zip in the render_template()

  return render_template("home.html", zip=zip)

Solution 4 - Python

I don't think templating languages allow doing zip of two containers over for loop. Here is a similar question for django and jinja templating is very close to django's.

You would have prebuild zipped container and pass to your template.

>> for i,j in zip(range(10),range(20,30)):
...     print i,j
... 

Is equivalent to

>>> [(i,j) for i,j in zip(range(10),range(20,30))]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn SalvatierView Question on Stackoverflow
Solution 1 - PythonGarrettView Answer on Stackoverflow
Solution 2 - PythonTheZekeView Answer on Stackoverflow
Solution 3 - PythonMantej SinghView Answer on Stackoverflow
Solution 4 - PythonSenthil KumaranView Answer on Stackoverflow