2014-11-06 47 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