2017-08-04 9 views
0

入力としてcsvを使用してjinj2テンプレートに基づいて出力を構築しようとしています。私は検索して解決策を構築するために多くの情報を見つけることができませんでした。jinja2テンプレートのループcsvコンテンツ

は、これまでのところ私は、次のコードを持っている:

import sys, os 
import jinja2 
import csv 

in_file="csv_file.csv" 
jinja_template = "test.j2" 
env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=".")) 

with open(in_file, "rb") as FD: 
    reader = csv.DictReader(FD) 
    for vals in reader: 
     gen_template = env.get_template(jinja_template) 
     output = gen_template.render(vals) 
     print output 

私のcsvファイルは次のようになります。

country,city 
UK,London 
UK,Manchester 
UK,Liverpool 
US,Chicago 
US,Denver 
US,Atlanta 

そして、私のJinja2のテンプレートは次のようになります。

country: {{country}} has cities {{city}} 

続いています出力私は達成しようとしています:

country: UK has cities: London, Manchester, Liverpool 
country: US has cities: Chicago, Denver, Atlanta 

私は、国の隣に都市名を構築するために、j2テンプレート内でforループを実行する必要があると思います。誰かが私はこれを達成することができます方法についていくつかのポインタを提供できるかどう

country: UK has cities London 
country: UK has cities Manchester 
country: UK has cities Liverpool 
country: US has cities Chicago 
country: US has cities Denver 
country: US has cities Atlanta 

感謝:私は上記のコードを実行すると

すると、実際に個々の国<はとして別々に、このような都市名>が取得します。

答えて

0

ご入力のcsvは国によってソートされ、itertools.groupbyは助けることができると仮定すると:あなたは神社内joinを行うことを好むならば、これはオプションです

from io import StringIO 
from jinja2 import Template 
from itertools import groupby 
from operator import itemgetter 
from csv import DictReader 


csv_data = '''country,city 
UK,London 
UK,Manchester 
UK,Liverpool 
US,Chicago 
US,Denver 
US,Atlanta 
''' 

tmpl = 'country: {{country}} has cities {{cities}}' 
template = Template(tmpl) 

with StringIO(csv_data) as file: 
    rows = DictReader(file) 
    for country, groups in groupby(rows, key=itemgetter('country')): 
     cities = ', '.join(row['city'] for row in groups) 
     output = template.render(country=country, cities=cities) 
     print(output) 

country: UK has cities London, Manchester, Liverpool 
country: US has cities Chicago, Denver, Atlanta 

を印刷しました:

tmpl = 'country: {{country}} has cities {{cities | join(", ")}}' 
template = Template(tmpl) 

with StringIO(csv_data) as file: 
    rows = DictReader(file) 
    for country, groups in groupby(rows, key=itemgetter('country')): 
     cities = (row['city'] for row in groups) 
     output = template.render(country=country, cities=cities) 

あなたはヘッダを追加できるようにする必要がある場合、あなたは(OrderedDictを使用して、ここで行われる)最初のファイルからすべてのデータを収集する必要があります。

その後、得
from collections import OrderedDict 

tmpl = '''Countries and cities: 
{%-for country, cities in grouped.items()%} 
country: {{coutry}} has cities {{cities | join(", ")}} 
{%-endfor%}''' 
template = Template(tmpl) 

with StringIO(csv_data) as file: 
    rows = DictReader(file) 
    grouped = OrderedDict() 
    for country, groups in groupby(rows, key=itemgetter('country')): 
     grouped[country] = [item['city'] for item in groups] 
    output = template.render(grouped=grouped) 
    print(output) 

Countries and cities: 
country: has cities London, Manchester, Liverpool 
country: has cities Chicago, Denver, Atlanta 
+0

はすばらしく、itertoolsについて詳しく読む予定です。 もう1つの質問ですが、別のテキストを追加すると、テンプレートファイルの見出しにも実際に何度も印刷されます。これはcsvファイルの内容と同じです。 ' '国:英国の都市を持っている:ロンドン、マンチェスター、Liverpool' 'これは、ファイルの見出しがある:どのように私は、このiは、テンプレートファイルに見出しを追加する場合のように、それがどのように見えるかである – zig

+0

ことを防ぐことができます 'これはファイルの見出しです:' '国:米国には都市があります:シカゴ、デンバー、アトランタ' – zig

+0

大丈夫です。あなたが必要としていることを希望... –

関連する問題