将namedtuple转换为python中的列表并生成CSV

时间:2014-07-19 11:03:01

标签: python python-2.7 csv

参考:https://stackoverflow.com/a/19726081/1182021

OrderedDict([
('company 1', tup(price=246, year='1991', month='march')),
('company 2', tup(price=245, year='1990', month='jan')),
('company 3', tup(price=243, year='1990', month='jan')),
('company 4', tup(price=247, year='1991', month='december')),
('company 5', tup(price=245, year='1991', month='june'))])

如何以csv格式导出此数据,如下所示:

Company Name , Price , Year , Month
Company 1    , 246   , 1991 , march
Company 2    , 245   , 1990 , jan

我尝试使用import csv这样创建一个csv( ALL IN SAME ROW ):

myfile = open(csvfile, 'wb')
wr = csv.writer(myfile , quoting=csv.QUOTE_ALL)
wr.writerow(data_list)

编辑1

其中data_list是OrderedDict,我得到的数据格式不正确

Company-A | Filtered(Year='2013', Month='Dec', Price=0) Company-B   | Filtered(Year='2013', Month='Dec', Price=0) |     Company-C  |    Filtered(Year='2013', Month='Dec', Price=0) |   Company-D |     Filtered(Year='2013', Month='Dec', Price=0) Company-E |     Filtered(Year='2013', Month='Dec', Price=0)

编辑2

好的,我按照data_list = OrderedDict.items()

将OrderedDict转换为简单列表

正如mkrehili所建议的那样,我将此作为我的导出方法:

def ExportData(csv_file, data_list):
    csv_file = open(csv_file, 'wb')
    wr = csv.writer(csv_file, quoting=csv.QUOTE_ALL)

    for company_name, company_data in data_list:
        wr.writerow([company_name] + list(company_data))

我现在正在获取此列表:

[('Company-A', Filtered(Year='2013', Month='Dec', Price=0)), ('Company-B', Filtered(Year='2013', Month='Dec', Price=0)), ('Company-C', Filtered(Year='2013', Month='Dec', Price=0)), ('Company-D', Filtered(Year='2013', Month='Dec', Price=0)), ('Company-E', Filtered(Year='2013', Month='Dec', Price=0))]

但是当我用CSV转换它时,输出如下:

Company-A   2013    Dec 0
Company-B   2013    Dec 0
Company-C   2013    Dec 0
Company-D   2013    Dec 0
Company-E   2013    Dec 0

编辑3 实际上两个数据都不相同:

在OrderedDict中:

OrderedDict([
('company A', tup(price=246, year='1991', month='march')),
('company B', tup(price=245, year='1990', month='jan')),
('company C', tup(price=243, year='1990', month='jan')),
('company D', tup(price=247, year='1991', month='december')),
('company E', tup(price=245, year='1991', month='june'))])

但是一旦我data_list = OrderedDict.items(),它就会给我这些数据:格式不正确:

[('Company-A', tup(price=0, year="2013", month='Dec')),
 ('Company-B', tup(price=0, year="2013", month='Dec')), 
 ('Company-C', tup(price=0, year="2013", month='Dec')), 
 ('Company-D', tup(price=0, year="2013", month='Dec')), 
 ('Company-E', tup(price=0, year="2013", month='Dec'))]

所以主要是我的问题是创建一个简单的列表,我有这样的列表:

Company Name , Price , Year , Month
Company A    , 246   , 1991 , march
Company B    , 245   , 1990 , jan
......
......

编辑4

with open(csv_file, 'w') as f:
    w = csv.writer(f)
    w.writerow(('Company Name', 'Year', 'Month', 'Price'))
    w.writerows([(name, data.year, data.month, data.price) for   name, data in data_list])`

这给了我正确的导出,但是在每行之后我有一个空行,如下所示:

Company Name    Year    Month   Price

Company-A   2000    Mar 1000

Company-B   2007    Mar 986

Company-C   1993    Jun 995

Company-D   2002    Apr 999

Company-E   2008    Oct 997

3 个答案:

答案 0 :(得分:6)

import csv
from collections import namedtuple, OrderedDict

tup = namedtuple('tup', ['price', 'year', 'month'])
prices = OrderedDict([
    ('company A', tup(price=246, year='1991', month='march')),
    ('company B', tup(price=245, year='1990', month='jan')),
    ('company C', tup(price=243, year='1990', month='jan')),
    ('company D', tup(price=247, year='1991', month='december')),
    ('company E', tup(price=245, year='1991', month='june'))])

with open('output.csv', 'w') as f:
    w = csv.writer(f)
    w.writerow(('Company Name', 'Price', 'Year', 'Month'))    # field header
    w.writerows([(name, data.price, data.year, data.month) for name, data in prices.items()])

写入output.csv:

Company Name,Price,Year,Month
company A,246,1991,march
company B,245,1990,jan
company C,243,1990,jan
company D,247,1991,december
company E,245,1991,june

答案 1 :(得分:1)

namedtuple仍然是可迭代的,所以请对待它:

>>> tup = namedtuple('tup', ['price', 'year', 'month'])
>>> c = tup(price=246, year='1991', month='march')
>>> list(c)
[246, '1991', 'march']
>>> print(*c)
246 1991 march

所以在你的例子中(你没有发布完整的代码,这会让事情变得更难):

for company_name, company_data in data_list.items():
    wr.writerow([company_name] + list(company_data))

答案 2 :(得分:0)

这是一个尊重问题标题的解决方案(提到命名元组而不是OrderedDict)。

像其他答案中那样的OrderedDict可能是一种更好的方法,但是我列出了它,以防万一它对可能不需要对行进行索引的其他人有用。

我制作了一个更通用的Gitlab代码段Name Tuple Demo: Saving a named tuple to csv,在此主题上有更多介绍。

from collections import namedtuple
import csv
from pathlib import Path


CompanyDetails = namedtuple(
    'CompanyDetails', ('company_name', 'price', 'year', 'month',)
)


def format_csv_header(header_fields):
    return tuple(
        header_field.replace("_", " ").title()
        for header_field in header_fields
    )


def write_contents_to_csv(contents, csv_file):
    with Path(csv_file).open('w') as outfile:
        writer = csv.writer(outfile)
        header = format_csv_header(contents._fields)
        rows = zip(*contents)
        all_rows = (header,) + (*rows,)
        writer.writerows(all_rows)


# Example: Row Indexed. Consider using OrderedDict here instead!
company_details = CompanyDetails(
    company_name=(
        'Company 1', 'Company 2', 'Company 3', 'Company 4', 'Company 5',
    ),
    price=(246, 245, 243, 247, 245,),
    year=('1991', '1990', '1990', '1991', '1991',),
    month=('march', 'jan', 'jan', 'december', 'june',)
)
write_contents_to_csv(company_details, '/tmp/company_details.csv')