我想使用python读取CSV数据,然后使用Jinja2输出它来制作平面文件HTML报告。我想使用的CSV数据如下:
State,City,Issue,Date
Michigan,Detroit,Economic Issues,12/11/14
Michigan,Detroit,Poor Schools,12/11/14
Michigan,Battle Creek,Economic Issues,2/12/14
Georgia,Atlanta,Lack of Transit,2/12/14
Georgia,Atlanta,Traffic,2/12/14
Georgia,Cummings,Economic Issues,12/11/14
Georgia,Cummings,Poor Schools,12/11/14
Georgia,Athens,Traffic,12/11/14
Florida,Miami,Weather Issues,12/11/14
Florida,Miami,Poor Schools,2/12/14
Florida,Miami,Economic Issues,2/12/14
Florida,Miami,Lack of Transit,2/12/14
Florida,Sarasota,Economic Issues,2/12/14
Florida,Levy,Poor Schools,2/12/14
Florida,Lee,Traffic,2/12/14
California,Los Angeles,Traffic,12/11/14
Alaska,Anchorage,Weather Issues,2/12/14
我希望每个州都有一行,然后每个州都有相关的问题和日期。
输出类似于:
Michigan
Detroit Economic Issues 12/11/2014
Poor Schools 12/11/2014
Battle Creek Economic Issues 02/12/2014
Georgia
Atlanta Lack of Transit 02/12/2014
Traffic 02/12/2014
Cummings Economic Issues 12/11/2014
我喜欢使用Jinja2并为此数据的输出创建模板。我的问题是,我不确定构建此数据然后移交给模板的最佳方法。
我应该创建一个国家字典,每个城市,问题和日期信息都是一个列表吗?它应该只是一个列表清单吗?我对数据结构的外观非常困惑,因此我可以轻松地在Jinja2模板中进行迭代。
答案 0 :(得分:1)
您可以使用groupby()
filter:
<table>
{% for state in csvrows|groupby('State') %}
<tr><td rowspan="4">{{ state.grouper }}</td></tr>
{% for city in state.list|groupby('City') %}
{% for row in city.list %}
<tr>
<td>{% if loop.first %}{{ row.City }}{% endif %}</td>
<td>{{ row.Issue }}</td>
<td>{{ row.Date }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
</table>
groupby()
过滤器生成组对象,每个对象都具有list
和grouper
属性。后者是构建组的值(因此外部循环中的State
值,下一循环中的City
),.list
属性是值的序列都具有相同的State
或City
值。
然后你需要生成的是一系列字典; groupby()
过滤器甚至可以为您排序数据。只需将一个csv.DictReader()
对象传递给Jinja2,就可以了。
Jinja中的groupby()
过滤器几乎与itertools.groupby()
function完全相同,您可以使用一些打印语句生成相同的所需输出:
>>> from itertools import groupby
>>> from operator import itemgetter
>>> state_key = itemgetter('State')
>>> for state, cities in groupby(sorted(rows, key=state_key), state_key):
... print state
... city_key = itemgetter('City')
... for city, group in groupby(sorted(cities, key=city_key), city_key):
... print '\t', city
... for row in group:
... print '\t\t', row['Issue'], row['Date']
...
Alaska
Anchorage
Weather Issues 2/12/14
California
Los Angeles
Traffic 12/11/14
Florida
Lee
Traffic 2/12/14
Levy
Poor Schools 2/12/14
Miami
Weather Issues 12/11/14
Poor Schools 2/12/14
Economic Issues 2/12/14
Lack of Transit 2/12/14
Sarasota
Economic Issues 2/12/14
Georgia
Athens
Traffic 12/11/14
Atlanta
Lack of Transit 2/12/14
Traffic 2/12/14
Cummings
Economic Issues 12/11/14
Poor Schools 12/11/14
Michigan
Battle Creek
Economic Issues 2/12/14
Detroit
Economic Issues 12/11/14
Poor Schools 12/11/14
这是直接从您的样本CSV数据生成的;过滤器也应用排序,就像上面的python示例一样。