2016-09-09 2 views
3

Я только начинаю изучать python и поэтому хотел бы создать таблицу html на основе имен файлов. визуализации следующие файлыpython create html table from dict

apple.good.2.svg 
apple.good.1.svg 
banana.1.ugly.svg 
banana.bad.2.svg 
kiwi.good.svg 

Вид объекта всегда первая часть (до первой точки) свойство качества находится где-то в названии.

Моя результирующая таблица должна выглядеть следующим образом:

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 
------------------------------------------------------------------------- 

Это то, что я сделал до сих пор

#!/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() 

мне удалось прочитать файлы, отсортированные в Словаре:

{'kiwi': ['kiwi.good.svg'], 'apple': ['apple.good.2.svg', 'apple.good.1.svg'], 'banana': ['banana.1.ugly.svg', 'banana.bad.2.svg']} 

Но не удается создать таблицу html.

enter image description here

Как я могу построить таблицу HTML, как показано выше? Где объекты записываются в первый первый столбец строки и имя файла в столбцах в зависимости от их свойства качества?

ответ

3

Вам необходимо выполнить итерацию всех комбинаций фруктов из ваших словарей и состояний, а затем создать одну строку (вместо одной колонки) для каждого фрукта. Затем просто переберите все файлы, соответствующие этому плоду, и отфильтруйте те, которые содержат текущее состояние, и присоедините их к одной ячейке.

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>" 

Результат:

enter image description here


Update: Если у вас есть государственные выражения, которые являются частью других государств, как bad и medium_bad, то только с помощью in не будет работать. Вместо этого вы можете использовать regular expression, чтобы получить наилучший результат.

>>> 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'] 

Вы можете использовать этот код, то:

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>" 

В качестве альтернативы, вы можете также перестроить свой словарь, чтобы иметь другой "слой" состояний, т.е. {"kiwi": {"good": ["kiwi.goog.svg"]}, ...}


Если вы хотите чтобы обернуть имена файлов в тегах изображений, вы можете добавить еще format в пределах join:

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

спасибо большое tobias_k! –

+0

еще один вопрос, скажем, мне нужны '_' и' .'as limiter '' _ {}. "' И имеют '* _bad.svg' и '* _medium_bad.svg' в моих именах файлов. 'medium_bad.svg' войдет в плохую колонку, так как она разделена с подчеркиванием. Есть ли способ обойти это? –

+0

Я просто подумал, может, это сработает, прежде чем работать с диктатором, чтобы заменить «medium_bad» на «medium-bad»? –