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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:13:56  来源:igfitidea点击:

python create html table from dict

python

提问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 表而失败。

enter image description here

在此处输入图片说明

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:

结果:

enter image description here

在此处输入图片说明



Update: If you have state expressions that are part of other states, like badand medium_bad, then just using inwon't work. Instead, you can use a regular expressionto get the best match.

更新:如果您的状态表达式是其他状态的一部分,例如badand 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 formatwithin the join:

如果你想图像标签内包裹的文件名,你可以把另一个formatjoin

html += "<td>{}</td>".format('<br>'.join('<img src="{}">'.format(f) for f in d[fruit] if by_state[f] == state))