2014-11-06 61 views
0

我有一个python字典,其中每个KEY可以有一个可变数量的VALUES(排列在列表中)。如何按键排序不均匀字典并创建CSV

例如:

{'607': [36146], '448': [50890, 44513], '626': [44349, 44436]} 

我想要做的就是生成的这种信息的CSV,象这样的格式:

448 , 607 , 626 
50890,36146,44349 
44513,  ,44436 

目前我的代码可以生成CSV如这是唯一的问题,即CSV的列未按照KEY的升序数字排序。到目前为止我的代码是下面:

csv_file = 'file.csv' 
with open(csv_file, 'wb') as fd: 
    writer = csv.writer(fd, delimiter = ',') 

    # Format headers for aesthetics 
    csv_headers = [' {} '.format(elem) for elem in dictionary.keys()] 

    writer.writerow(headers) 

    # Format data to create convenient csv format 
    csv_data = itertools.izip_longest(*dictionary.values(), fillvalue = '  ') 
    writer.writerows(csv_data) 

正如你看到的我是从价值观分裂密钥,并将它们分开来写,但如果我想通过键的列进行排序我想这可能不是最好的办法去做这件事。因此,我希望有人能指出我正确的(也是最pythonic)方向。

回答

2

你有两个选择:

  • 排序键,然后以相同的顺序提取值,而不是依靠dictionary.values()
  • 使用csv.DictWriter() object并产生每行的字典。

选项1是这样的:

csv_file = 'file.csv' 
with open(csv_file, 'wb') as fd: 
    writer = csv.writer(fd, delimiter=',') 

    keys = sorted(dictionary) 
    # Format headers for aesthetics 
    headers = [' {} '.format(key) for key in keys] 
    writer.writerow(headers) 

    # Format data to create convenient csv format 
    csv_data = itertools.izip_longest(*(dictionary[key] for key in keys), 
             fillvalue='  ') 
    writer.writerows(csv_data) 

使用DictWriter会是什么样子:

csv_file = 'file.csv' 
with open(csv_file, 'wb') as fd: 
    writer = csv.DictWriter(
     fd, sorted(dictionary), delimiter=',') 
    # write formatted headers 
    writer.writerow({k: ' {} '.format(k) for k in dicitonary}) 

    csv_data = itertools.izip_longest(*dictionary.values(), fillvalue='  ') 
    writer.writerows(dict(zip(dictionary, row)) for row in csv_data) 
+0

我怎样才能做到这一点与我的字典不平衡的性质?我曾试图使用csv.Dictwriter,但它不能很好地与每个列表中的可变数量的条目... – user1182556 2014-11-06 12:34:21

+0

太棒了!选项1的作用像一个魅力,然而,选项2不写入标题值?另外,你认为哪一种是pythonic方法? – user1182556 2014-11-06 12:53:50

+0

@ user1182556:我忘了调用'writeheader()'方法.. – 2014-11-06 12:56:40

1

我去整理并用key一个换位元组结束了与的一个iterable名单,然后从那里去:

import csv 
from itertools import izip_longest 

d = {'607': [36146], '448': [50890, 44513], '626': [44349, 44436]} 

with open('output.csv', 'wb') as fout: 
    csvout = csv.writer(fout) 
    header, rows = zip(*sorted((k, iter(v)) for k, v in d.iteritems())) 
    csvout.writerow(format(el, '^5') for el in header) 
    csvout.writerows(izip_longest(*rows, fillvalue='  ')) 
+0

不错,但'iter()这里的调用是多余的,如果你存储一个列表引用或者列表迭代器对象引用并不重要,但是后者将由'izip_longest()'创建。 – 2014-11-06 14:10:54