本文针对前面利用Python 所做的一次数据匹配实验,整理了其中的一些对于csv文件的读写操作和常用的Python'数据结构'(如字典和列表)之间的转换
(Python Version 2.7)


csv文件与列表之间的转换

  • 将列表转换为csv文件

  • 将嵌套字典的列表转换为csv文件

将列表转换为csv文件

最基本的转换,将列表中的元素逐行写入到csv文件中

def list2csv(list, file):wr = csv.writer(open(file, 'wb'), quoting=csv.QUOTE_ALL)for word in list:wr.writerow([word])

将嵌套字典的列表转换为csv文件

这种属于典型的csv文件读写,常见的csv文件常常是第一行为属性栏,标明各个字段,接下来每一行都是对应属性的值,读取时常常用字典来存储(key为第一行的属性,value为对应行的值),例如

my_list = [{'players.vis_name': 'Khazri', 'players.role': 'Midfielder', 'players.country': 'Tunisia','players.last_name': 'Khazri', 'players.player_id': '989', 'players.first_name': 'Wahbi','players.date_of_birth': '08/02/1991', 'players.team': 'Bordeaux'},{'players.vis_name': 'Khazri', 'players.role': 'Midfielder', 'players.country': 'Tunisia','players.last_name': 'Khazri', 'players.player_id': '989', 'players.first_name': 'Wahbi','players.date_of_birth': '08/02/1991', 'players.team': 'Sunderland'},{'players.vis_name': 'Lewis Baker', 'players.role': 'Midfielder', 'players.country': 'England','players.last_name': 'Baker', 'players.player_id': '9574', 'players.first_name': 'Lewis','players.date_of_birth': '25/04/1995', 'players.team': 'Vitesse'}]

而最后所有的字典嵌套到一个列表中存储,而接下来是一个逆过程,即将这种嵌套了字典的列表还原为csv文件存储起来

# write nested list of dict to csv
def nestedlist2csv(list, out_file):with open(out_file, 'wb') as f:w = csv.writer(f)fieldnames=list[0].keys()  # solve the problem to automatically write the headerw.writerow(fieldnames)for row in list:w.writerow(row.values())

注意其中的fieldnames用于传递key即第一行的属性

csv文件与字典之间的转换

  • csv文件转换为字典

    • 第一行为key,其余行为value

    • 每一行为key,value的记录

  • csv文件转换为二级字典

  • 字典转换为csv文件

    • 第一行为key,其余行为value

    • 每一行为key,value的记录

csv文件转换为字典

第一行为key,其余行为value

针对常见的首行为属性,其余行为值的情形

# convert csv file to dict
# @params:
# key/value: the column of original csv file to set as the key and value of dict
def csv2dict(in_file,key,value):new_dict = {}with open(in_file, 'rb') as f:reader = csv.reader(f, delimiter=',')fieldnames = next(reader)reader = csv.DictReader(f, fieldnames=fieldnames, delimiter=',')for row in reader:new_dict[row[key]] = row[value]return new_dict

其中的new_dict[row[key]] = row[value]中的'key''value'是csv文件中的对应的第一行的属性字段,需要注意的是这里假设csv文件比较简单,所指定的key是唯一的,否则直接从csv转换为dict文件会造成重复字段的覆盖而丢失数据,如果原始数据指定作为key的列存在重复的情况,则需要构建列表字典,将value部分设置为list,可参照列表字典的构建部分代码

每一行为key,value的记录

针对每一行均为键值对的特殊情形
这里默认认为第一列为所构建的字典的key,而第二列对应为value,可根据需要进行修改

# convert csv file to dict(key-value pairs each row)
def row_csv2dict(csv_file):dict_club={}with open(csv_file)as f:reader=csv.reader(f,delimiter=',')for row in reader:dict_club[row[0]]=row[1]return dict_club

[更新]

字典列表

构造有值为列表的字典,主要适用于需要把csv中的某些列对应的值作为某一个列的值的情形
或者说本身并不适合作为单纯的字典结构,同一个键对应的值不唯一

# build a dict of list like {key:[...element of lst_inner_value...]}
# key is certain column name of csv file
# the lst_inner_value is a list of specific column name of csv file
def build_list_dict(source_file, key, lst_inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:for element in lst_inner_value:new_dict.setdefault(row[key], []).append(row[element])return new_dict
# sample:
# test_club=build_list_dict('test_info.csv','season',['move from','move to'])
# print test_club

csv文件转换为二级字典

这个一般是特殊用途,将csv文件进一步结构化,将其中的某一列(属性)所对应的值作为key,然后将其余键值对构成子字典作为value,一般用于匹配时优先过滤来建立一种层级结构提高准确度
例如我有csv文件的记录如下(以表格形式表示)

id name age country
1 danny 21 China
2 Lancelot 22 America
... ... ... ...

经过二级字典转换后(假设构建country-name两级)得到如下字典

dct={'China':{'danny':{'id':'1','age':'21'}}'America':{'Lancelot':{'id':'2','age':'22'}}}

代码如下

# build specific nested dict from csv files(date->name)
def build_level2_dict(source_file):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row['country'], dict())item[row['name']] = {k: row[k] for k in ('id','age')}new_dict[row['country']] = itemreturn new_dict

[更新]
进一步改进后可以使用更加灵活一点的方法来构建二级字典,不用修改内部代码,二是指定传入的键和值,有两种不同的字典构建,按需查看

  • 构建的二级字典的各层级的键值均人为指定为某一列的值

# build specific nested dict from csv files
# @params:
#   source_file
#   outer_key:the outer level key of nested dict
#   inner_key:the inner level key of nested dict
#   inner_value:set the inner value for the inner key
def build_level2_dict2(source_file,outer_key,inner_key,inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row[outer_key], dict())item[row[inner_key]] = row[inner_value]new_dict[row[outer_key]] = itemreturn new_dict
  • 指定第一层和第二层的字典的键,而将csv文件中剩余的键值对存储为最内层的值

# build specific nested dict from csv files
# @params:
#   source_file
#   outer_key:the outer level key of nested dict
#   inner_key:the inner level key of nested dict,and rest key-value will be store as the value of inner key
def build_level2_dict(source_file,outer_key,inner_key):new_dict = {}with open(source_file, 'rb')as csv_file:reader = csv.reader(csv_file, delimiter=',')fieldnames = next(reader)inner_keyset=fieldnamesinner_keyset.remove(outer_key)inner_keyset.remove(inner_key)csv_file.seek(0)data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row[outer_key], dict())item[row[inner_key]] = {k: row[k] for k in inner_keyset}new_dict[row[outer_key]] = itemreturn new_dict

还有另一种构建二级字典的方法,利用的是pop()方法,但是个人觉得不如这个直观,贴在下面

def build_dict(source_file):projects = defaultdict(dict)# if there is no header within the csv file you need to set the header # and utilize fieldnames parameter in csv.DictReader method# headers = ['id', 'name', 'age', 'country']with open(source_file, 'rb') as fp:reader = csv.DictReader(fp, dialect='excel', skipinitialspace=True)for rowdict in reader:if None in rowdict:del rowdict[None]nationality = rowdict.pop("country")date_of_birth = rowdict.pop("name")projects[nationality][date_of_birth] = rowdictreturn dict(projects)

[更新]
另外另种构造二级字典的方法,主要是针对csv文件并不适合直接构造单纯的字典结构,某些键对应多个值,所以需要在内部用列表来保存值,或者对每一个键值对用列表保存

用列表保存键值对
# build specific nested dict from csv files
# @params:
#   source_file
#   outer_key:the outer level key of nested dict
#   lst_inner_value: a list of column name,for circumstance that the inner value of the same outer_key are not distinct
#   {outer_key:[{pairs of lst_inner_value}]}
def build_level2_dict3(source_file,outer_key,lst_inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:new_dict.setdefault(row[outer_key], []).append({k: row[k] for k in lst_inner_value})return new_dict
用列表保存值域
# build specific nested dict from csv files
# @params:
#   source_file
#   outer_key:the outer level key of nested dict
#   lst_inner_value: a list of column name,for circumstance that the inner value of the same outer_key are not distinct
#   {outer_key:{key of lst_inner_value:[...value of lst_inner_value...]}}
def build_level2_dict4(source_file,outer_key,lst_inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:# print rowitem = new_dict.get(row[outer_key], dict())# item.setdefault('move from',[]).append(row['move from'])# item.setdefault('move to', []).append(row['move to'])for element in lst_inner_value:item.setdefault(element, []).append(row[element])new_dict[row[outer_key]] = itemreturn new_dict
# build specific nested dict from csv files
# @params:
#   source_file
#   outer_key:the outer level key of nested dict
#   lst_inner_key:a list of column name
#   lst_inner_value: a list of column name,for circumstance that the inner value of the same lst_inner_key are not distinct
#   {outer_key:{lst_inner_key:[...lst_inner_value...]}}
def build_list_dict2(source_file,outer_key,lst_inner_key,lst_inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:# print rowitem = new_dict.get(row[outer_key], dict())item.setdefault(row[lst_inner_key], []).append(row[lst_inner_value])new_dict[row[outer_key]] = itemreturn new_dict# dct=build_list_dict2('test_info.csv','season','move from','move to')

构造三级字典

类似的,可以从csv重构造三级字典甚至多级字典,方法和上面的类似,就不赘述了,只贴代码

# build specific nested dict from csv files
# a dict like {outer_key:{inner_key1:{inner_key2:{rest_key:rest_value...}}}}
# the params are extract from the csv column name as you like
def build_level3_dict(source_file,outer_key,inner_key1,inner_key2):new_dict = {}with open(source_file, 'rb')as csv_file:reader = csv.reader(csv_file, delimiter=',')fieldnames = next(reader)inner_keyset=fieldnamesinner_keyset.remove(outer_key)inner_keyset.remove(inner_key1)inner_keyset.remove(inner_key2)csv_file.seek(0)data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row[outer_key], dict())sub_item = item.get(row[inner_key1], dict())sub_item[row[inner_key2]] = {k: row[k] for k in inner_keyset}item[row[inner_key1]] = sub_itemnew_dict[row[outer_key]] = itemreturn new_dict# build specific nested dict from csv files
# a dict like {outer_key:{inner_key1:{inner_key2:inner_value}}}
# the params are extract from the csv column name as you like
def build_level3_dict2(source_file,outer_key,inner_key1,inner_key2,inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row[outer_key], dict())sub_item = item.get(row[inner_key1], dict())sub_item[row[inner_key2]] = row[inner_value]item[row[inner_key1]] = sub_itemnew_dict[row[outer_key]] = itemreturn new_dict

这里同样给出两种根据不同需求构建字典的方法,一种是将剩余的键值对原封不动地保存为最内部的值,另一种是只取所需要的键值对保留。

此外还有一种特殊情形,当你的最内部的值不是一个单独的元素而需要是一个列表来存储多个对应同一个键的元素,则只需要对于最内部的键值对进行修改

# build specific nested dict from csv files
# a dict like {outer_key:{inner_key1:{inner_key2:[inner_value]}}}
# for multiple inner_value with the same inner_key2,thus gather them in a list
# the params are extract from the csv column name as you like
def build_level3_dict3(source_file,outer_key,inner_key1,inner_key2,inner_value):new_dict = {}with open(source_file, 'rb')as csv_file:data = csv.DictReader(csv_file, delimiter=",")for row in data:item = new_dict.get(row[outer_key], dict())sub_item = item.get(row[inner_key1], dict())sub_item.setdefault(row[inner_key2], []).append(row[inner_value])item[row[inner_key1]] = sub_itemnew_dict[row[outer_key]] = itemreturn new_dict

其中的核心部分是这一句
sub_item.setdefault(row[inner_key2], []).append(row[inner_value])

字典转换为csv文件

  • 每一行为key,value的记录

  • 第一行为key,其余行为value

  • 输出列表字典

每一行为key,value的记录

前述csv文件转换为字典的逆过程,比较简单就直接贴代码啦

def dict2csv(dict,file):with open(file,'wb') as f:w=csv.writer(f)# write each key/value pair on a separate roww.writerows(dict.items())
第一行为key,其余行为value
def dict2csv(dict,file):with open(file,'wb') as f:w=csv.writer(f)# write all keys on one row and all values on the nextw.writerow(dict.keys())w.writerow(dict.values())
输出列表字典

其实这个不太常用,倒是逆过程比较常见,就是从常规的csv文件导入到列表的字典(本身是一个字典,csv文件的首行构成键,其余行依次构成对应列下的键的值,其中值形成列表),不过如果碰到这种情形要保存为csv文件的话,做法如下

import csv
import pandas as pd
from collections import OrderedDictdct=OrderedDict()
dct['a']=[1,2,3,4]
dct['b']=[5,6,7,8]
dct['c']=[9,10,11,12]header = dct.keys()
rows=pd.DataFrame(dct).to_dict('records')with open('outTest.csv', 'wb') as f:f.write(','.join(header))f.write('\n')for data in rows:f.write(",".join(str(data[h]) for h in header))f.write('\n')

这里用到了三个包,除了csv包用于常规的csv文件读取外,其中OrderedDict用于让csv文件输出后保持原有的列的顺序,而pandas则适用于中间的一步将列表构成的字典转换为字典构成的列表,举个例子

[('a', [1, 2, 3, 4]), ('b', [5, 6, 7, 8]), ('c', [9, 10, 11, 12])]
to
[{'a': 1, 'c': 9, 'b': 5}, {'a': 2, 'c': 10, 'b': 6}, {'a': 3, 'c': 11, 'b': 7}, {'a': 4, 'c': 12, 'b': 8}]

特殊的csv文件的读取

这个主要是针对那种分隔符比较特殊的csv文件,一般情形下csv文件统一用一种分隔符是关系不大的(向上述操作基本都是针对分隔符统一用,的情形),而下面这种第一行属性分隔符是,而后续值的分隔符均为;的读取时略有不同,一般可逐行转换为字典在进行操作,代码如下:

def func(id_list,input_file,output_file):with open(input_file, 'rb') as f:# if the delimiter for header is ',' while ';' for rowsreader = csv.reader(f, delimiter=',')fieldnames = next(reader)reader = csv.DictReader(f, fieldnames=fieldnames, delimiter=';')        rows = [row for row in reader if row['players.player_id'] in set(id_list)]# operation on rows...

可根据需要修改分隔符中的内容.

关于csv文件的一些操作我在实验过程中遇到的问题大概就是这些啦,大部分其实都可以在stackoverflow上找到或者自己提问解决,上面的朋友还是很给力的,后续会小结一下实验过程中的一些对数据的其他处理如格式转换,除重,重复判断等等

最后,源码我发布在github上的csv_toolkit里面,欢迎随意玩耍~


更新日志
1、2016-12-22: 改进了构建二级字典的方法,使其变得更加灵活
2、2016-12-24 14:55:30: 加入构造三级字典的方法
3、2017年1月9日11:26:59: 最内部可保存制定列的元素列表
4、2017年1月16日10:29:44:加入了列表字典的构建;针对特殊二级字典的构建(需要保存对应同一个键的多个值);
5、2017年2月9日10:54:41: 加入新的二级列表字典的构建
6、2017年2月10日11:18:01:改进了简单的csv文件到字典的构建代码

csv文件与字典,列表等之间的转换小结【Python】相关推荐

  1. Python数据分析·读取CSV文件转为字典

    Python数据分析·读取CSV文件转为字典 1.pandas 读取CSV 2.CSV转为字典 3.CSV转为数组 Python pandas包可以直接读取CSV文件,为了接下来的数据分析,考虑到转为 ...

  2. python文件写入字典格式输出_python基础——4、python应用(文件操作,字典,列表,输出格式)——(YZ)...

    本次的内容为python的应用,关于文件.字典.统计应用,均多应用列表.字典. 习题一 读入文件pmi_days.csv,完成以下操作: 1.统计质量等级对应的天数,例如: 优:5天 良:3天 中度污 ...

  3. python将csv文件转换为列表_如何将csv文件数据转换成列表?

    仍未解决的部分 我正在尝试转换csv文件中存储的数据'存储.txt'以使我可以更有效地使用它很容易.就像目前,我的文件存储中的项目如下:Leroy,55349234,ok@gmail.com Sati ...

  4. python操作csv文件第7行开始的数据_Python教程-Python读写CSV文件

    前言 本教程学习在Python中使用CSV文件.CSV(逗号分隔值)格式是在电子表格和数据库中使用的非常流行的导入和导出格式.Python语言包含该模块,该模块具有用于读取和写入CSV格式的数据的类. ...

  5. python导入csv文件是如何预览后10行-使用python中的csv reader只读取前N行csv文件

    我将一些csv文件的第二列中包含的文本添加到一个列表中,以便稍后对列表中的每个项目执行情绪分析.我的代码目前完全适用于大型csv文件,但是我对列表中的项目执行的情感分析花费了太长时间,这就是为什么我只 ...

  6. python如何读取csv文件某几行某几列_关于python:读取.csv文件时,我似乎无法指定列dtypes...

    本问题已经有最佳答案,请猛点这里访问. 一个菜鸟问题(修订):我读了一个.csv文件,并尝试按以下方式指定dtypes: 1 2 3 4 5 6 7 8 9 10 11 12 13 14import ...

  7. Python爬虫:url中带字典列表参数的编码转换

    平时见到的url参数都是key-value, 一般vlaue都是字符串类型的 如果有幸和我一样遇到字典,列表等参数,那么就幸运了 python2代码 import json from urllib i ...

  8. python导入csv文件中特定列-如何使用标头完整的python导入csv文件,其中第一列为非数字...

    Python csv模块按行处理数据,这是查看此类数据的常用方法. 您似乎想要按列的方法. 这是一种方法. 假设您的文件名为myclone.csv并且包含 workers,constant,age w ...

  9. 复数的实部虚部与幅值相角之间的转换及python代码实现

    一.复数定义 复数 z=a+biz=a+biz=a+bi 的实部为 aaa,虚部为 bbb.复数的模长 ∣z∣|z|∣z∣ 定义为 ∣z∣=a2+b2|z|=\sqrt{a^2+b^2}∣z∣=a2+ ...

最新文章

  1. php多表头表格,HTML多表头表格代码示例
  2. 解决hash冲突的常用方法
  3. android 程序安装路径选择
  4. nginx日志切割定时执行脚本
  5. DL:深度学习模型概览(包括DNN、CNN、RNN等)的简介、网络结构简介、使用场景对比之详细攻略
  6. 4.mysql数据库创建,表创建模等模板脚本,mysql_SQL99标准的连接查询(内连接,外连接,满外连接,交叉连接)
  7. Climbing Stairs - Print Path
  8. 一位资深程序员大牛给Java初学者的学习建议
  9. ios开发 热搜词demo_手机app如何开发
  10. java打字游戏代码_牛逼啊!一个随时随地写Python代码的神器
  11. 基于JAVA+SpringMVC+MYSQL的进销存管理系统
  12. LeNet的详细网络结构
  13. vs有断点就卡死_再分享 5 个 vs 调试技巧
  14. python中33个保留字的含义_Python的保留字。这是什么意思?
  15. 【STL源码剖析】STL六大组件功能与运用(目录)
  16. python 拼图验证码
  17. 0805,0603,1206这些封装的名字是什么来的
  18. Excel查看多列重复项
  19. jquery查子元素
  20. canvas画圆形图片

热门文章

  1. LeetCode 226. Invert Binary Tree--反转二叉树--C++,Python解法--递归,迭代做法
  2. Debian/Ubuntu/Centos下编译安装RocksDB
  3. mfc 访问局域网mysql_数据库操作:MFC连接与MYSQL
  4. Centos7安装Elasticsearch
  5. html完整表格结构,正确认识html表格(table)的结构
  6. php时间处理类,PHP常见的日期处理
  7. android 5秒后进入,Android/Java:如何在5秒后停止下载?
  8. 引入三方库_关于使用第三方库、代码复用的一些思考
  9. jquery的html,text,val的区别
  10. oracle procedures批量删除带索引条件数据很慢_见微知著,数据库应用设计优化浅谈...