【问题标题】:Convert a dictionary of lists to two-column csv将列表字典转换为两列 csv
【发布时间】:2018-06-23 12:41:16
【问题描述】:

我有一个列表字典如下:

{'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'

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

谢谢。

【问题讨论】:

  • 你以二进制模式打开index_filename,因为你传递了'b',因此Python需要bytes而不是str。省略'b',改为以文本模式打开文件,即可写入字符串数据。

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


【解决方案1】:

如果您想让您的代码更高效,重要的是,您要说明您想让代码更高效的内容。除了糟糕的解决方案之外,在合理的解决方案中,通常还需要在空间(内存)和时间(循环、函数调用)之间进行权衡。

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

像 Python 中的 dict 之类的元组非常高效,因为它们在内部到处使用。 Python 中的大多数函数调用都涉及在底层创建元组(用于位置参数)。

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

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

您仍然拥有中间元组,但它们是在您迭代字典项时动态计算的。此解决方案比显式列表更节省内存,尤其是在您有很多条目的情况下。

您也可以直接将嵌套循环放入 with 正文中:

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 模块进行测量。

【讨论】:

    【解决方案2】:

    您正在以二进制/字节模式打开文件,该模式由“wb”中的“b”指定。这是python2时代很多人做的事情,当时“str”和“bytes”是同一个东西,所以很多老书还是这样教的。

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

    f.write(some_str_variable.encode()
    

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

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

    【讨论】:

      猜你喜欢
      • 2014-04-24
      • 2020-01-03
      • 2014-03-01
      • 2019-02-01
      • 1970-01-01
      • 2017-04-23
      • 2021-10-13
      • 2021-01-28
      相关资源
      最近更新 更多