2016-11-11 60 views
1

我知道,当使用python写入csv文件的字典时,标题将按字母顺序放置。那么有没有一种方法可以用我想要的顺序编写标题?写字典到csv文件与键不按字母顺序

tsv文件的代码和输出如下。

我有一个字典:

my_data = {"name": name[:], "city": city[:], "state": state[:], 
      "stars": stars[:], "review_count": review_count[:], 
      "main_category": new_cat[:]} 

我用下面的代码来写他们在csv文件:

with open('test.tsv','w') as file: 
    writer = csv.writer(file, delimiter='\t') 
    writer.writerow(my_data.keys()) 
    for row in zip(*my_data.values()): 
     writer.writerow(list(row)) 

而TSV文件的输出的前几行是如下:

city review_count name main_category state stars 
Los Angeles 2 Southern California Medical Group Medical Centers CA 3.5 
Cambridge 4 Harvard Square Shiatsu Massage MA 4.0 
Kitchener 2 Faith & Glory Collective Tattoo ON 4.0 

你可以看到他们放在一个字母顺序,但我真正想要的是他们可以按照my_data中的顺序排列如下:

name city state stars review_count main_category 
+0

是否一个或多个这个问题的答案做你想做什么?:http:// stackoverflow。com/questions/1885324/is-it-it-it-it-it-it-it-the-python-csv-dictreader –

+0

但是Dict没有'fieldnames'属性..还有另一种方法吗? – Parker

+0

'my_data'中的键没有定义的顺序,因为它是一个字典,而不是一个序列。 – martineau

回答

0

下面显示了一对夫妇的方式来输出你想要的数据的顺序TSV文件:

with open('test.tsv', 'wb') as file: 
    FIELDNAMES = 'name city state stars review_count main_category'.split() 
    writer = csv.writer(file, delimiter='\t') 
    writer.writerow(FIELDNAMES) 
    writer.writerows(row for row in zip(*(my_data[key] for key in FIELDNAMES))) 

正如其他人所建议的,这也可以通过使用csv.DictWriter完成:

with open('test.tsv', 'wb') as file: 
    FIELDNAMES = 'name city state stars review_count main_category'.split() 
    writer = csv.DictWriter(file, delimiter='\t', fieldnames=FIELDNAMES) 
    writer.writeheader() 
    writer.writerows(dict(zip(FIELDNAMES, row)) 
         for row in zip(*(my_data[key] for key in FIELDNAMES))) 

正如你可以看到有两个大约相同数量的代码,虽然第一,非DictWriter版本是因为生产一点点更有效每个row的数据需要较少的努力,所以相应地它可能快一些。

无论哪种写入器的类型被使用,创建将是完全相同的test.tsv文件的内容,如下所示(其中,表示的标签分离器):

name→city→state→stars→review_count→main_category 
Southern California Medical Group→Los Angeles→CA→3.5→2→Medical Centers 
Harvard Square Shiatsu→Cambridge→MA→4.0→4→Massage 
Faith & Glory Collective→Kitchener→ON→4.0→2→Tattoo 

:如果你正在使用Python 2,你打开输出文件以用'wb'模式写入。对于Python 2,您应该使用模式'w'并添加一个newline=''关键字参数。

+0

非常感谢!除第一行数据丢失之外,完美工作。我认为我应该从range(0,..)开始 – Parker

+0

不用客气,并且对'range()'需要改变的调用是正确的。它的方式是因为我错误地重建了my_data的内容(因为你的问题中显示的内容不足以用于测试目的)。我建议你在发布任何进一步的问题之前阅读[如何创建最小,完整和可验证的示例_](https://stackoverflow.com/help/mcve)。 – martineau

+0

已更新答案,以便不再需要使用'range()'。还展示了如何使用'csv.DictWriter'和'csv.writer'对象来完成。 – martineau

1

只有一条记录。

import csv 

output=open('temp.csv', 'w') 
outputCSV = csv.DictWriter(output, delimiter = '\t', \ 
    fieldnames = [ 'name', 'city', 'state', 'stars', 'review_count', 'main_category' ]) 

outputCSV.writerow({ 
    'name': 'Southern Cal Med Group', 
    'city': 'Los Angeles', 
    'state': 'CA', 
    'review_count': '2', 
    'main_category': 'medical', 
    'stars': '3.5', 
    }) 

output.close() 
+0

我有一个非常大的字典。当我这样做:打开('test1.tsv','w')作为文件: writer = csv.DictWriter(file,delimiter ='\ t',fieldnames = [“name”,“city”,“状态”, “星星”, “REVIEW_COUNT”, “main_category” 的行中的zip]) (* my_data): writer.writerow(名单(行))我有一个ValueError “字典包含不字段名田” – Parker

+0

所以使用字段名的事情是,当我继续写Writer时,自从这个大字典的第二行开始,我会得到valueerror,这些值不是字段名 – Parker

+0

**这听起来像是一个新问题。我有点惊讶,因为我相信它正在期待一个字典,所以编剧并没有因为收到名单而抱怨。我会说,只要把你输入到编辑器的字典削减一下。 –

0

如果您有每行字段的字典,则使用DictWriter。它有多个选项可以填写缺失字段的缺省值,或者忽略输出中不需要的额外字段。

实施例:

import csv 

# Sample data converted to a list of lines. 
datalines = '''\ 
Los Angeles,2,Southern California Medical Group,Medical Centers,CA,3.5 
Cambridge,4,Harvard Square Shiatsu,Massage,MA,4.0 
Kitchener,2,Faith & Glory Collective,Tattoo,ON,4.0 
'''.splitlines() 

# Specify the fields you want in the output. 
# If your dictionaries have fields you don't want in the output, use extrasaction='ignore' 
fields = 'name city state stars review_count main_category'.split() 

# Python 3, use newline=''. Python 2 use 'wb' instead. 
with open('test.tsv','w',newline='') as file: 
    writer = csv.DictWriter(file, fields, delimiter='\t', extrasaction='ignore') 

    writer.writeheader() # Writes headers specified by "fields" 

    for line in datalines: 
     # Converts input line into a dict in OP's format. 
     my_data = dict(zip('city review_count name main_category state stars'.split(),line.split(','))) 
     print(my_data) 
     writer.writerow(my_data) 

输出来验证词典在OP的格式:

{'stars': '3.5', 'review_count': '2', 'name': 'Southern California Medical Group', 'city': 'Los Angeles', 'state': 'CA', 'main_category': 'Medical Centers'} 
{'stars': '4.0', 'review_count': '4', 'name': 'Harvard Square Shiatsu', 'city': 'Cambridge', 'state': 'MA', 'main_category': 'Massage'} 
{'stars': '4.0', 'review_count': '2', 'name': 'Faith & Glory Collective', 'city': 'Kitchener', 'state': 'ON', 'main_category': 'Tattoo'} 

输出到test.tsv(→为标签):

name→city→state→stars→review_count→main_category 
Southern California Medical Group→Los Angeles→CA→3.5→2→Medical Centers 
Harvard Square Shiatsu→Cambridge→MA→4.0→4→Massage 
Faith & Glory Collective→Kitchener→ON→4.0→2→Tattoo