将dicts列表转换为wiki格式

时间:2018-01-31 20:03:13

标签: python dictionary confluence

我有一个看起来像这样的dicts列表(可能看起来像这样,我真的不知道它们包含哪些数据):

data = [
  {'k1': 'v1-a', 'k2': 'v2-a', 'k3': 'v3-a'},
  {'k1': 'v1-b', 'k3': 'v3-b'},
  {'k1': 'v1-c', 'k2': 'v2-c', 'k3': 'v3-c'},
  {'k1': 'v1-d', 'k2': 'v2-d', 'k3': 'v3-d'}
]

目标是将其变成一个如下所示的字符串:

||k1||k2||k3||
|v1-a|v2-a|v3-a|
|v1-b||v3-b|
|v1-c|v2-c|v3-c|
|v1-d|v2-d|v3-d|

这是针对confluence wiki format

问题本身并不复杂,但我提出的解决方案是如此丑陋以至于我几乎不想使用它。

我目前得到的是:

from pandas import DataFrame
// data = ...
df = DataFrame.from_dict(data).fillna('')
body = '||{header}||\n{data}'.format(
  header='||'.join(df.columns.values.tolist()),
  data='\n'.join(['|{}|'.format('|'.join(i)) for i in df.values.tolist()])
)

这不仅仅是丑陋的,它取决于熊猫,这是巨大的(我不想仅仅依靠这个库)! 如果有一个很好的方法来获取标题列表和dict中的值列表列表,上面的解决方案将在没有pandas的情况下工作。但是python 2并不保证字典顺序,所以我不能指望.values()给我正确的信息。

我错过了itertoolscollections中的任何内容吗?

3 个答案:

答案 0 :(得分:1)

这适用于Python 3和2.7。试一试:https://repl.it/repls/VividMediumturquoiseAlbino

all_keys = sorted({key for dic in data for key in dic.keys()})

header = "||" + "||".join(all_keys) + "||"

lines = [header]

for row in data:
    elems_on_row = [row.get(key, "") for key in all_keys]
    current_row = "|" + "|".join(elems_on_row) + "|"
    lines.append(current_row)

wikistr = "\n".join(lines)
print(wikistr)

答案 1 :(得分:0)

纯Python中的答案是遍历列表,因此每个字典两次。 在第一次运行中,您可以收集所有不同的键,在第二次运行中,您可以构建您的wiki格式化字符串输出。

我们首先收集可以将集合用作存储的密钥:

keys = set()
for dict_ in data:
    keys.update(set(dict_.keys())

keys = sorted(keys)

现在我们有了一组唯一键,我们可以再次浏览列表输出:

wiki_output = ''

wiki_output = '||' + '||'.join(keys) + '||' 

for dict_ in data:
    for key in keys:
        wiki_output += '|' + dict_.get(key, '')
    wiki_output += '|\n'

我们去......

答案 2 :(得分:0)

一种方法是使用csv.DictWriter来处理格式,StringIO收集输入,defaultdict进行一些创意作弊。这是否更漂亮是有争议的。

from StringIO import StringIO
from collections import defaultdict
from csv import DictWriter

output = StringIO()
keys = list(set(key for datum in data for key in datum.keys()))
header = '|'.join('|{}|'.format(key) for key in keys)
output.write(header + '\n')

fields = [''] + keys + [''] # provides empty fields for starting and ending |
writer = DictWriter(output, fields, delimiter = '|')

for row in data:
    writer.writerow(defaultdict(str, **row)) # fills in the empty fields

output.seek(0)
result = output.read()

如何运作

  • 通过创建一个包含任何一个词典中所有键的集合来创建标题列表。
  • 制作一个使用'|'的DictWriter为了它的分隔符,在条目之间获取管道。
  • 在开头和结尾添加空字符串标题,以便写入开始和结束管道。
  • 使用defaultdict提供空的开始和结束值,因为它们不在词典中。