写一个字典列表,每个键的多个值作为新行

问题描述:

为了序言,会出现很多重复的问题,但没有一个解决方案对我有帮助。我平时的代码,我用它编写的词典列表,使用CSV包:写一个字典列表,每个键的多个值作为新行

import csv 
    to_csv = list_dic 
    keys = to_csv[0].keys() 
    with open('output.csv', 'w') as output_file: 
     dict_writer = csv.DictWriter(output_file, keys) 
     dict_writer.writeheader() 
     dict_writer.writerows(to_csv) 

单键值就好了(好词典列表上使用时,该代码的工作,不是事实,其他输出CSV有一个空行每隔一行),但现在我有每个键多个值的词典列表,就像下面的例子:

list_dic = [{'a':[x,y],'b':[1,2],'c':[1,2]}, 
       {'a':[x,y],'b':[1,2],'c':[1,2]}, 
       {'a':[x,y],'b':[1,2],'c':[1,2]}, 
       {'a':[x,y],'b':[1,2],'c':[1,2]}] 

基本上我的CSV输出目前看起来是这样的:

 'a'  'b'  'c' 
    [x,y] [1,2] [1,2] 
    [x,y] [1,2] [1,2] 
    [x,y] [1,2] [1,2] 
    [x,y] [1,2] [1,2] 

而且我想来到这里:

 'a' 'b' 'c' 
     x  1  1 
     y  2  2 
     x  1  1 
     y  2  2 
     x  1  1 
     y  2  2 
     x  1  1 
     y  2  2   

我已经经历非常类似的问题倒,但似乎无法在任何解决方案,适用于我的特殊情况。我试过使用某种形式的语句来写多行,但是失败了。

感谢您的帮助,如果您知道任何与此情况相同的问题,请指出正确的方向。

编辑:例子每个键2倍的值,但值的数量在实践中是未知的,只是> 1

+0

就个人而言,我不喜欢使用CSV。您的输入是制表符分隔的吗?如果是这样,你能举例吗?我可以展示我将如何接近它。我认为使用defaultdict()可能会更好。它可以给你一个关键:列表(值),你可以根据列表中的位置轻松解析。 –

+0

@ st.ph.n不幸的是我的输入不是制表符分隔的 – YungBoy

如果压缩和足够的解压缩数据,你会得到你想要的格式:对于只有一个zip是需要转columnsrows

list_dic = [{'a':['x','y'],'b':[1,2],'c':[1,2]}, 
      {'a':['x','y'],'b':[1,2],'c':[1,2]}, 
      {'a':['x','y'],'b':[1,2],'c':[1,2]}, 
      {'a':['x','y'],'b':[1,2],'c':[1,2]}] 
import csv 
to_csv = list_dic 
keys = to_csv[0].keys() 
with open('output.csv', 'w') as output_file: 
    dict_writer = csv.DictWriter(output_file, keys) 
    dict_writer.writeheader() 
    for dic in list_dic: 
     keys, values = zip(*dic.items()) 
     for values in zip(*values): 
      dict_writer.writerow(dict(zip(keys, values))) 
+0

男人,我需要在zip上教育自己......这段代码实现了我一直在寻找的东西。谢谢! – YungBoy

+0

我创建的输出文件是有效的,并检出。也许只是运气?将调查更多虽然 – YungBoy

+1

@EricDuminil - 是的,你错过了什么。输出顺序在构建“DictWriter”时确定。第二个arg到'DictWriter()'的顺序将决定每次调用'.writerow()'的顺序。 –

拆分字典,然后通过你的CSV运行它们:

def split_dict(dct): 
    result = [] 
    result.append({k: v[0] for k, v in dct.items()}) 
    result.append({k: v[1] for k, v in dct.items()}) 
    return result 

def list_dict_split(lst): 
    result = [] 
    for dct in lst: 
     result.extend(split_dict(dct)) 
    return result 

现在只是降list_dict_split(list_dic)无论你有list_dic:

中级名单是:

[{'a': 'x', 'c': 1, 'b': 1}, 
{'a': 'y', 'c': 2, 'b': 2}, 
{'a': 'x', 'c': 1, 'b': 1}, 
{'a': 'y', 'c': 2, 'b': 2}, 
{'a': 'x', 'c': 1, 'b': 1}, 
{'a': 'y', 'c': 2, 'b': 2}, 
{'a': 'x', 'c': 1, 'b': 1}, 
{'a': 'y', 'c': 2, 'b': 2}] 
+0

我可能应该在我的问题中更清楚(将编辑),这对每个键恰好有2个值很有效。但是说我有300或20或任意数量的值N.如何调整你写的第一个函数来解决这个问题?添加300多行result.append显然不现实。某种'对于每个价值'的陈述? – YungBoy

+0

@YungBoy所有键都有相同数量的值吗? – TemporalWolf

+0

是的,这是一件事情,在我的情况下永远是真的 – YungBoy

这里是一个另类,:

x = 'x' 
y = 'y' 

list_dic = [{'a': [x, y], 'b':[1, 2], 'c':[1, 2]}, 
      {'a': [x, y], 'b':[3, 4], 'c':[1, 2]}, 
      {'a': [x, y], 'b':[1, 2], 'c':[1, 2]}, 
      {'a': [x, y], 'b':[3, 4], 'c':[1, 2]}] 

keys = ['a', 'b', 'c'] 
sep = "\t" 

print(sep.join(keys)) 
for dic in list_dic: 
    columns = [dic[key] for key in keys] 
    for row in zip(*columns): 
     print(sep.join(str(cell) for cell in row)) 

它输出:

a b c 
x 1 1 
y 2 2 
x 3 1 
y 4 2 
x 1 1 
y 2 2 
x 3 1 
y 4 2 

你可以把字典的当前列表进入爆炸词典列表和然后将其写入到CSV:

>>> import itertools as it 
>>> [dict(n) for d in list_dic for n in zip(*(zip(it.repeat(k), v) for k, v in d.items()))] 
[{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 2, 'c': 2}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 2, 'c': 2}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 2, 'c': 2}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 2, 'c': 2}] 

这工作与价值观的任意数目:

>>> list_dic = [{'a':['x','y','z'],'b':[1,2,3],'c':[1,2,3]}, 
...    {'a':['x','y','a'],'b':[1,3,2],'c':[1,2,1]}, 
...    {'a':['x','y','b'],'b':[1,4,3],'c':[1,2,4]}, 
...    {'a':['x','y','a'],'b':[1,5,2],'c':[1,2,9]}] 
>>> [dict(n) for d in list_dic for n in zip(*(zip(it.repeat(k), v) for k, v in d.items()))] 
[{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 2, 'c': 2}, 
{'a': 'z', 'b': 3, 'c': 3}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 3, 'c': 2}, 
{'a': 'a', 'b': 2, 'c': 1}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 4, 'c': 2}, 
{'a': 'b', 'b': 3, 'c': 4}, 
{'a': 'x', 'b': 1, 'c': 1}, 
{'a': 'y', 'b': 5, 'c': 2}, 
{'a': 'a', 'b': 2, 'c': 9}]