找到你要的答案

Q:Python - Using eval() to put a CSV into a dictionary

Q:用()把CSV到字典python

Hey I wonder if you can help me, I did some research on using eval() to read the lines of my CSV and then put it into a dictionary. The problem is that my CSV has 4 pieces of data: the name, the first score, the second score and the third score. How would I transfer this data from a CSV into a dictionary within python so then later on I can check if that users name is the dictionary to append to it or edit the score.

I would like to have it so the key the name, and the scores are the list and are kept in a list so they can be appended to/deleted later.

Thanks for your help.

嘿,我想知道你是否能帮助我,我也用()读我的CSV线的一些研究,然后把它放进字典。问题是,我的CSV有4件资料:姓名、总分第一、第二得分第三分。我怎么会把这个数据从CSV到字典在Python这样之后我可以检查用户的名字是字典添加或编辑评分。

我想有它的关键名称,和分数是列表,并保存在列表中,以便他们可以附加/删除后。

谢谢你的帮助。

answer1: 回答1:

There is a module in the Python standard library that will help you with reading/writing CSV files. Let me assume that your csv file looks like this:

Jim, 45, 78, 90
Mary, 100,98, 99
Molly, 78, 45,46
Mat, 76, 89, 95

Then:

import csv                                                                                                                                   
scores = {}                                                                                                                                         
with open('score.csv') as f:                                                                                                                 
    reader = csv.reader(f)                                                                                                                   
    for row in reader:                                                                                                                                                                                                                                                    
       scores.setdefault(row[0],[]).extend(row[1:])  

This will create a dictionary scores with names as keys and a list of scores as values:

{'Mat': [' 76', ' 89', ' 95'], 'Jim': [' 45', ' 78', ' 90'], 'Molly': [' 78', ' 45', '46'], 'Mary': [' 100', '98', ' 99']}

在Python标准库将帮助你读/写CSV文件模块。让我假设你的CSV文件看起来像这样:

Jim, 45, 78, 90
Mary, 100,98, 99
Molly, 78, 45,46
Mat, 76, 89, 95

然后:

import csv                                                                                                                                   
scores = {}                                                                                                                                         
with open('score.csv') as f:                                                                                                                 
    reader = csv.reader(f)                                                                                                                   
    for row in reader:                                                                                                                                                                                                                                                    
       scores.setdefault(row[0],[]).extend(row[1:])  

这将创建一个字典的分数与名称作为键和一个列表的分数作为值:

{'Mat': [' 76', ' 89', ' 95'], 'Jim': [' 45', ' 78', ' 90'], 'Molly': [' 78', ' 45', '46'], 'Mary': [' 100', '98', ' 99']}
answer2: 回答2:
import csv
from collections import defaultdict

# Your target is a dictionary {name : [scores]}
scores = defaultdict(list)
with open(csvfilename) as csvfile:
    for row in csv.reader(csvfile):
        scores[row[0]].extend(row[1:])

I don't think eval is a good tool for this. It is really easy to introduce security vulnerabilities with it, as it will parse and execute whatever you pass it. As an exercise, think about why it may not be okay to execute data from some csv-file. Spoiler: your csv-file is a serialization format, this talk Tom Eastman - Serialization formats are not toys - PyCon 2015 shows dangers that may exist there. For bonus insights look at the source of the collections module we imported the defaultdict from and think about why this use of exec by @raymond-hettinger is different from using eval on data.

import csv
from collections import defaultdict

# Your target is a dictionary {name : [scores]}
scores = defaultdict(list)
with open(csvfilename) as csvfile:
    for row in csv.reader(csvfile):
        scores[row[0]].extend(row[1:])

我不想评价是一个很好的工具。这是很容易引入安全漏洞与它,因为它会分析和执行任何你通过它。作为一个练习,想想为什么不能从CSV文件执行数据好。剧透:你的CSV文件是一个序列化格式,这跟汤姆伊士曼-序列化格式不是玩具- pycon 2015显示可能存在的危险。奖金的见解看收藏模块源采用defaultdict从想想为什么使用exec的@雷蒙德赫廷杰不同于使用eval数据。

answer3: 回答3:

eval() is not what you want here I don't think. eval() reads a string and interprets it as python code; what you want is simple file I/O manipulation.

data = numpy.genfromtxt("filename.csv", delimter=";")  # non-numpy possibilities available
my_dict = {}
for i in data:
    my_dict[data[i,0]] = data[i,1:]

()是不是你要的在这里,我不想。()读取一个字符串,并把它解释为Python代码;你想要的是简单的文件I/O操作。

data = numpy.genfromtxt("filename.csv", delimter=";")  # non-numpy possibilities available
my_dict = {}
for i in data:
    my_dict[data[i,0]] = data[i,1:]
answer4: 回答4:

If you really, really want to do it with eval: Well, first, you shouldn't, unless you have a very good reason. Just parse the file as CSV, not as Python code. The right way to do that is with the csv module, as in Chris Wesseling's answer (or, if you're already using NumPy or Pandas, using their functions).

But if you really, really, really want to, can you?

Well, sometimes.

The most basic CSV dialect doesn't quote strings, so its lines aren't going to be valid as Python code. And some CSV dialects handle embedded quotes in ways that either aren't valid in Python, or mean something different.

But some dialects do happen to make at least most rows legal, and meaningful, as Python tuple literals consisting of Python str, int, and float literals. And for those dialects, technically, yes, you could parse them with eval, like this:

scores = {}
with open(path) as f:
    for line in f:
        name, *newscores = eval(line)
        scores.setdefault(name, []).extend(newscores)

But again, you shouldn't.

And even if you really, really, really want to do this, you should at least use literal_eval instead; it will handle all the same legal values that eval would without opening the big gaping security holes (e.g., someone putting __import__('os').system('rm -rf /') in a CSV) and painful-to-debug edge cases.

But even with literal_eval, you don't want it. You want to parse the actual CSV dialect you have, not just treat it as a similar but different language and cross your fingers.

如果你真的,真的想用eval这样做:嗯,首先,你不应该,除非你有一个很好的理由。只是解析文件为CSV,不是Python代码。正确的做法是用csv模块,如Chris Wesseling的回答(或者,如果你已经在使用NumPy或熊猫,使用功能)。

但是,如果你真的,真的,真的想,你能吗?

嗯,有时。

最基本的CSV方言不引用字符串,所以它的行不会被视为有效的Python代码。和一些CSV方言处理方式,无论是不是有效的Python嵌入引号,或意味着不同的东西。

但有些方言不发生,至少大多数行法律,和有意义的,因为Python元组文字由Python str,int,漂浮文字。对于那些方言,从技术上讲,是的,你可以解析与评价,像这样:

scores = {}
with open(path) as f:
    for line in f:
        name, *newscores = eval(line)
        scores.setdefault(name, []).extend(newscores)

但是,你不应该。

即使你真的,真的,真的想这样做,你至少应该用literal_eval相反;它将处理所有相同的法律价值观,评价会不开大的安全漏洞(例如,有人把__import__('os”)。系统('rm射频/”)在CSV)和痛苦的调试边缘情况。

但即使literal_eval,你不想要它。你想解析实际CSV方言的你,不只是把它作为一个相似但不同的语言和交叉你的手指。

python  csv  dictionary  eval