将列表字典转换为双列csv

时间:2018-01-14 19:55:29

标签: python list csv dictionary csv-write-stream

我有一份列表字典如下:

{'banana': [1,2],
 'monkey': [5],
 'cow': [1,5,0],
 ...}

我想编写一个包含一个数字和单词的csv,如下所示:

1 | banana
2 | banana
5 | monkey
1 | cow
5 | cow
0 | cow
...

与|作为分隔符。

我尝试将其转换为元组列表,并按如下方式编写:

for k, v in dic.items():
    for ID in v: 
        rv.append((ID, k))

with open(index_filename,'wb') as out:
    csv_out=csv.writer(out, delimiter='|')
    csv_out.writerow(['identifier','descriptor'])
    for row in rv:
        csv_out.writerow(row)

但是运行了这个错误:

a bytes-like object is required, not 'str'

有没有比转换为元组更有效的方法,如果没有,我的代码有什么问题?

感谢。

2 个答案:

答案 0 :(得分:0)

您正在以二进制/字节模式打开文件,该模式由" b"在" wb"。这是许多人在python2天所做的事情,当时" str"和"字节"同样的事情,很多旧书仍然以这种方式教它。

如果以字节模式打开文件,则必须为其写入字节,而不是字符串。可以使用str方法将str.encode()转换为字节:

f.write(some_str_variable.encode()

但是,你可能想要的是不以字节模式打开文件。

with open(index_filename, 'w') as out:
    ...

答案 1 :(得分:0)

如果您希望提高代码的效率,请务必说明您想要提高效率的代码。除了糟糕的解决方案之外,在合理的解决方案中,通常还需要在空间(内存)和时间(周期,函数调用)之间进行权衡。

除了效率之外,还应考虑可读性和可维护性。在进行任何优化之前。

像Python中的dicts这样的元组是非常有效的,因为它们在内部使用。 Python中的大多数函数调用都涉及元组创建(用于位置参数)。

关于具体示例,您可以使用生成器表达式来避免临时列表:

entries = ((k, v) for k, l in dic.items() for v in l)

您仍然拥有中间元组,但是在迭代字典项时,它们是动态计算的。这个解决方案比显式列表更有内存效率,特别是如果你有很多条目。

您也可以将嵌套循环直接放入with body:

with open(index_filename,'wb') as out:
    csv_out=csv.writer(out, delimiter='|')
    csv_out.writerow(['identifier','descriptor'])
    for k, v in dic.items():
        for ID in v: 
            csv_out.writerow((k, ID))

为避免重复调用writerow函数,您还可以使用writerows,这可能会更快。

with open(index_filename,'wb') as out:
    csv_out=csv.writer(out, delimiter='|')
    csv_out.writerow(['identifier','descriptor'])
    csv_out.writerows((k, v) for k, l in dic.items() for v in l)

如果你真的感兴趣,哪种方法最快,你可以使用Python的timeit模块进行测量。