从csv文件创建字典?

drb*_*sen 125 python csv dictionary list-comprehension

我正在尝试从csv文件创建一个字典.csv文件的第一列包含唯一键,第二列包含值.csv文件的每一行代表字典中唯一的键值对.我试图使用csv.DictReadercsv.DictWriter类,但我只能弄清楚如何为每一行生成一个新的字典.我想要一本字典.这是我尝试使用的代码:

import csv

with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
    writer = csv.writer(outfile)
    for rows in reader:
        k = rows[0]
        v = rows[1]
        mydict = {k:v for k, v in rows}
    print(mydict)
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,我得到了一个ValueError: too many values to unpack (expected 2).如何从csv文件创建一个字典?谢谢.

Nat*_*ate 137

我相信你要找的语法如下:

with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
        writer = csv.writer(outfile)
        mydict = {rows[0]:rows[1] for rows in reader}
Run Code Online (Sandbox Code Playgroud)

或者,对于python <= 2.7.1,您需要:

mydict = dict((rows[0],rows[1]) for rows in reader)
Run Code Online (Sandbox Code Playgroud)

  • 我在 csv 中有多行,但它只给出了 1 个键:值对 (3认同)
  • 很好地说明行超过预期; 但如果连续的项目太多,他不应该提出自己的例外吗?我认为这意味着他的输入数据存在错误. (2认同)

Lax*_*khi 62

通过调用open然后打开文件csv.DictReader.

input_file = csv.DictReader(open("coors.csv"))
Run Code Online (Sandbox Code Playgroud)

您可以通过遍历input_file来迭代csv文件dict reader对象的行.

for row in input_file:
    print row
Run Code Online (Sandbox Code Playgroud)

或仅访问第一行

dictobj = csv.DictReader(open('coors.csv')).next() 
Run Code Online (Sandbox Code Playgroud)

  • 这使得 DictReader 对象不是字典(并且不是键值对) (8认同)
  • @HN Singh - 是的,我知道 - 目的是它也会帮助其他人 (2认同)
  • @Palak - 它是针对 Python 2.7 的,在 Python 3+ 版本中尝试使用 `next(dictobj)` 而不是 `dictobj.next()`。 (2认同)

rob*_*ert 55

import csv
reader = csv.reader(open('filename.csv', 'r'))
d = {}
for row in reader:
   k, v = row
   d[k] = v
Run Code Online (Sandbox Code Playgroud)

  • @Alex Laskin:真的吗?对我来说,它看起来像一个非常可读的python.你支持这个陈述的原则是什么?你基本上只称他为"poopy head"...... (39认同)
  • @Alex Laskin:谢谢你的澄清.我个人同意你的观点,但我认为,如果你要将某人的代码称为"非pythonic",那么你应该以合理的方式附上该评论.我会说"更短"和"更快"并不一定等同于"更多pythonic".可读性/可靠性也是一个巨大的问题.如果我们将某些约束条件更容易地用于上述"读取行中的行"范式,那么它(在长期开发之后)可能更加实用.我同意你的短期,但要注意过早优化. (38认同)
  • @机器向往,不,我没有说他的代码是'坏'.但是,没有一个理由可以在阅读器中写入`for row:k,v = row`,例如,如果你可以简单地写一个`for k,v in reader`.如果你期望,那个阅读器是一个可迭代的,产生两个元素的项目,那么你可以简单地将它直接传递给dict进行转换.`d = dict(reader)`在大型数据集上更短,速度更快. (22认同)
  • 高度非pythonic风格. (6认同)
  • @罗伯特:谢谢伙计!真的很有帮助。其他代码太难读了。 (2认同)

mud*_*n19 24

这不是优雅,而是使用熊猫的一线解决方案.

import pandas as pd
pd.read_csv('coors.csv', header=None, index_col=0, squeeze=True).to_dict()
Run Code Online (Sandbox Code Playgroud)

如果要为索引指定dtype(如果因为错误而使用index_col参数,则无法在read_csv中指定):

import pandas as pd
pd.read_csv('coors.csv', header=None, dtype={0: str}).set_index(0).squeeze().to_dict()
Run Code Online (Sandbox Code Playgroud)

  • 在我的书中,这是最好的答案 (2认同)
  • @ndtreviv您可以使用skiprows来忽略标题。 (2认同)

Ale*_*kin 16

你必须将csv.reader转换为dict:

~ >> cat > 1.csv
key1, value1
key2, value2
key2, value22
key3, value3

~ >> cat > d.py
import csv
with open('1.csv') as f:
    d = dict(filter(None, csv.reader(f)))

print(d)

~ >> python d.py
{'key3': ' value3', 'key2': ' value22', 'key1': ' value1'}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案是整洁的,如果他能确定**他的输入在某一行中永远不会有三列或更多列,那么它将会很有用.但是,如果遇到过这种情况,会引发类似这样的异常:`ValueError:字典更新序列元素#2的长度为3; 2是必需的. (4认同)

Thi*_*iru 11

你也可以使用numpy.

from numpy import loadtxt
key_value = loadtxt("filename.csv", delimiter=",")
mydict = { k:v for k,v in key_value }
Run Code Online (Sandbox Code Playgroud)


Tri*_*ath 8

单线解决方案

import pandas as pd

dict = {row[0] : row[1] for _, row in pd.read_csv("file.csv").iterrows()}
Run Code Online (Sandbox Code Playgroud)


yel*_*w01 6

对于简单的 csv 文件,例如以下

id,col1,col2,col3
row1,r1c1,r1c2,r1c3
row2,r2c1,r2c2,r2c3
row3,r3c1,r3c2,r3c3
row4,r4c1,r4c2,r4c3
Run Code Online (Sandbox Code Playgroud)

您可以仅使用内置函数将其转换为 Python 字典

with open(csv_file) as f:
    csv_list = [[val.strip() for val in r.split(",")] for r in f.readlines()]

(_, *header), *data = csv_list
csv_dict = {}
for row in data:
    key, *values = row   
    csv_dict[key] = {key: value for key, value in zip(header, values)}
Run Code Online (Sandbox Code Playgroud)

这应该产生以下字典

{'row1': {'col1': 'r1c1', 'col2': 'r1c2', 'col3': 'r1c3'},
 'row2': {'col1': 'r2c1', 'col2': 'r2c2', 'col3': 'r2c3'},
 'row3': {'col1': 'r3c1', 'col2': 'r3c2', 'col3': 'r3c3'},
 'row4': {'col1': 'r4c1', 'col2': 'r4c2', 'col3': 'r4c3'}}
Run Code Online (Sandbox Code Playgroud)

注意:Python 字典有唯一的键,所以如果你的 csv 文件有重复,ids你应该将每一行附加到一个列表中。

for row in data:
    key, *values = row

    if key not in csv_dict:
            csv_dict[key] = []

    csv_dict[key].append({key: value for key, value in zip(header, values)})
Run Code Online (Sandbox Code Playgroud)


Joh*_*ooy 5

我建议添加if rows以防文件末尾有空行

import csv
with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
        writer = csv.writer(outfile)
        mydict = dict(row[:2] for row in reader if row)
Run Code Online (Sandbox Code Playgroud)


con*_*mak 5

假设您有一个这种结构的 CSV:

"a","b"
1,2
3,4
5,6
Run Code Online (Sandbox Code Playgroud)

并且您希望输出为:

[{'a': '1', ' "b"': '2'}, {'a': '3', ' "b"': '4'}, {'a': '5', ' "b"': '6'}]
Run Code Online (Sandbox Code Playgroud)

zip 函数(尚未提及)很简单而且很有帮助。

def read_csv(filename):
    with open(filename) as f:
        file_data=csv.reader(f)
        headers=next(file_data)
        return [dict(zip(headers,i)) for i in file_data]
Run Code Online (Sandbox Code Playgroud)

如果你更喜欢熊猫,它也可以很好地做到这一点:

import pandas as pd
def read_csv(filename):
    return pd.read_csv(filename).to_dict('records')
Run Code Online (Sandbox Code Playgroud)

  • 它适用于我的用例。 (2认同)