我有一份列表字典如下:
{'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'
有没有比转换为元组更有效的方法,如果没有,我的代码有什么问题?
感谢。
答案 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模块进行测量。