python从dict创建html表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39412679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
python create html table from dict
提问by t Book
I′m just starting learning python and therefore like to create a html table based on filenames. Imaging following files
我刚刚开始学习python,因此喜欢根据文件名创建一个html表。对以下文件进行成像
apple.good.2.svg
apple.good.1.svg
banana.1.ugly.svg
banana.bad.2.svg
kiwi.good.svg
The kind of object is always the first part (before the first dot) the quality property is somewhere in the name.
对象的种类总是第一部分(在第一个点之前),质量属性在名称的某处。
My resulting table should look like this:
我的结果表应该是这样的:
Object Name | good | bad | ugly
-------------------------------------------------------------------------
apple | apple.good.1.svg |
| apple.good.2.svg |
-------------------------------------------------------------------------
banana | | banana.bad.2.svg | banana.1.ugly.svg
-------------------------------------------------------------------------
kiwi | kiwi.good.svg
-------------------------------------------------------------------------
This is what I did so far
这是我到目前为止所做的
#!/usr/bin/python
import glob
from collections import defaultdict
fileNames = defaultdict(list)
# fill sorted list of tables based on svg filenames
svgFiles = sorted(glob.glob('*.svg'))
for s in svgFiles:
fileNames[s.split('.', 1)[0]].append(s)
# write to html
html = '<html><table border="1"><tr><th>A</th><th>' + '</th><th>'.join(dict(fileNames).keys()) + '</th></tr>'
for row in zip(*dict(fileNames).values()):
html += '<tr><td>Object Name</td><td>' + '</td><td>'.join(row) + '</td></tr>'
html += '</table></html>'
file_ = open('result.html', 'w')
file_.write(html)
file_.close()
I managed to read the files sorted in a dict:
我设法阅读了按字典排序的文件:
{'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
But fail by generating the html table.
但是由于生成 html 表而失败。
How can I build the html table as shown above? Where Objects are written to the first first column of a row and the filename in columns depending on their quality property?
如何构建如上所示的 html 表?对象在哪里写入行的第一列和列中的文件名取决于它们的质量属性?
回答by tobias_k
You have to iterate all combinations of fruits from your dictionaries and states, and then create one line (instead of one column) for each fruit. Then just iterate all the files matching that fruit and filter those that contain the current state and join those in one cell.
您必须迭代字典和状态中的所有水果组合,然后为每个水果创建一行(而不是一列)。然后只需迭代与该水果匹配的所有文件并过滤那些包含当前状态的文件并将它们加入一个单元格中。
d = {'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
html = """<html><table border="1">
<tr><th>Object</th><th>Good</th><th>Bad</th><th>Ugly</th></tr>"""
for fruit in d:
html += "<tr><td>{}</td>".format(fruit)
for state in "good", "bad", "ugly":
html += "<td>{}</td>".format('<br>'.join(f for f in d[fruit] if ".{}.".format(state) in f))
html += "</tr>"
html += "</table></html>"
Result:
结果:
Update: If you have state expressions that are part of other states, like bad
and medium_bad
, then just using in
won't work. Instead, you can use a regular expressionto get the best match.
更新:如果您的状态表达式是其他状态的一部分,例如bad
and medium_bad
,那么仅使用是in
行不通的。相反,您可以使用正则表达式来获得最佳匹配。
>>> fruit = "banana_bad.svg", "banana_medium_bad.svg"
>>> [re.search(r"[._](good|bad|medium_bad|ugly)[._]", f).group(1) for f in fruit]
['bad', 'medium_bad']
You could use this code then:
然后您可以使用此代码:
d = {'kiwi': ['kiwi.good.svg', 'kiwi_medium_bad.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
states = ['good', 'bad', 'medium_bad', 'ugly']
html = """<html><table border="1">
<tr><th>Object</th><th>{}</th></tr>""".format("</th><th>".join(states))
for fruit in d:
html += "<tr><td>{}</td>".format(fruit)
by_state = {f: re.search(r"[._]({})[._]".format('|'.join(states)), f).group(1) for f in d[fruit]}
for state in states:
html += "<td>{}</td>".format('<br>'.join(f for f in d[fruit] if by_state[f] == state))
html += "</tr>"
html += "</table></html>"
Alternatively, you could also restructure your dictionary to have another "layer" of states, i.e. {"kiwi": {"good": ["kiwi.goog.svg"]}, ...}
或者,您也可以重组您的字典以拥有另一个“层”状态,即 {"kiwi": {"good": ["kiwi.goog.svg"]}, ...}
If you want to wrap the filenames within image tags, you can put another format
within the join
:
如果你想图像标签内包裹的文件名,你可以把另一个format
内join
:
html += "<td>{}</td>".format('<br>'.join('<img src="{}">'.format(f) for f in d[fruit] if by_state[f] == state))