python create html table from dict
<p>IÂ´m just starting learning python and therefore like to create a html table based on filenames. 
Imaging following files</p>

<pre><code>apple.good.2.svg
apple.good.1.svg
banana.1.ugly.svg
banana.bad.2.svg
kiwi.good.svg
</code></pre>

<p>The kind of object is always the first part (before the first dot) the quality property is somewhere in the name.</p>

<p>My resulting table should look like this:</p>

<pre><code>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
-------------------------------------------------------------------------
</code></pre>

<p>This is what I did so far</p>

<pre><code>#!/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 = '&lt;html&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;' + '&lt;/th&gt;&lt;th&gt;'.join(dict(fileNames).keys()) + '&lt;/th&gt;&lt;/tr&gt;'

for row in zip(*dict(fileNames).values()):
    html += '&lt;tr&gt;&lt;td&gt;Object Name&lt;/td&gt;&lt;td&gt;' + '&lt;/td&gt;&lt;td&gt;'.join(row) + '&lt;/td&gt;&lt;/tr&gt;'

html += '&lt;/table&gt;&lt;/html&gt;'

file_ = open('result.html', 'w')
file_.write(html)
file_.close()
</code></pre>

<p>I managed to read the files sorted in a dict:</p>

<pre><code>{'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}
</code></pre>

<p>But fail by generating the html table. </p>

<p><a href="http://i.stack.imgur.com/E79th.png" rel="nofollow"><img src="http://i.stack.imgur.com/E79th.png" alt="enter image description here"></a></p>

<p>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?</p>

<p>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.</p>

<pre><code>d = {'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']}

html = """&lt;html&gt;&lt;table border="1"&gt;
&lt;tr&gt;&lt;th&gt;Object&lt;/th&gt;&lt;th&gt;Good&lt;/th&gt;&lt;th&gt;Bad&lt;/th&gt;&lt;th&gt;Ugly&lt;/th&gt;&lt;/tr&gt;"""
for fruit in d:
    html += "&lt;tr&gt;&lt;td&gt;{}&lt;/td&gt;".format(fruit)
    for state in "good", "bad", "ugly":
        html += "&lt;td&gt;{}&lt;/td&gt;".format('&lt;br&gt;'.join(f for f in d[fruit] if ".{}.".format(state) in f))
    html += "&lt;/tr&gt;"
html += "&lt;/table&gt;&lt;/html&gt;"
</code></pre>

<p>Result:</p>

<p><a href="http://i.stack.imgur.com/cLxq9.png" rel="nofollow"><img src="http://i.stack.imgur.com/cLxq9.png" alt="enter image description here"></a></p>

<hr>

<p>Update: If you have state expressions that are part of other states, like <code>bad</code> and <code>medium_bad</code>, then just using <code>in</code> won't work. Instead, you can use a <a href="https://docs.python.org/3/library/re.html#re.search" rel="nofollow">regular expression</a> to get the best match. </p>

<pre><code>&gt;&gt;&gt; fruit = "banana_bad.svg", "banana_medium_bad.svg"
&gt;&gt;&gt; [re.search(r"[._](good|bad|medium_bad|ugly)[._]", f).group(1) for f in fruit]
['bad', 'medium_bad']
</code></pre>

<p>You could use this code then:</p>

<pre><code>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 = """&lt;html&gt;&lt;table border="1"&gt;
&lt;tr&gt;&lt;th&gt;Object&lt;/th&gt;&lt;th&gt;{}&lt;/th&gt;&lt;/tr&gt;""".format("&lt;/th&gt;&lt;th&gt;".join(states))
for fruit in d:
    html += "&lt;tr&gt;&lt;td&gt;{}&lt;/td&gt;".format(fruit)
    by_state = {f: re.search(r"[._]({})[._]".format('|'.join(states)), f).group(1) for f in d[fruit]}
    for state in states:
        html += "&lt;td&gt;{}&lt;/td&gt;".format('&lt;br&gt;'.join(f for f in d[fruit] if by_state[f] == state))
    html += "&lt;/tr&gt;"
html += "&lt;/table&gt;&lt;/html&gt;"
</code></pre>

<p>Alternatively, you could also restructure your dictionary to have another "layer" of states, i.e. <code>{"kiwi": {"good": ["kiwi.goog.svg"]}, ...}</code></p>

<hr>

<p>If you want to wrap the filenames within image tags, you can put another <code>format</code> within the <code>join</code>:</p>

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

python