Python 导入 csv 到列表
Posted
技术标签:
【中文标题】Python 导入 csv 到列表【英文标题】:Python import csv to list 【发布时间】:2014-08-31 00:05:20 【问题描述】:我有一个包含大约 2000 条记录的 CSV 文件。
每条记录都有一个字符串和一个类别:
This is the first line,Line1
This is the second line,Line2
This is the third line,Line3
我需要将此文件读入如下所示的列表中:
data = [('This is the first line', 'Line1'),
('This is the second line', 'Line2'),
('This is the third line', 'Line3')]
如何使用 Python 将此 CSV 导入我需要的列表?
【问题讨论】:
然后使用csv
模块:docs.python.org/2/library/csv.html
如果有适合您问题的答案,请采纳。
How do I read and write CSV files with Python?的可能重复
【参考方案1】:
使用csv module:
import csv
with open('file.csv', newline='') as f:
reader = csv.reader(f)
data = list(reader)
print(data)
输出:
[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
如果你需要元组:
import csv
with open('file.csv', newline='') as f:
reader = csv.reader(f)
data = [tuple(row) for row in reader]
print(data)
输出:
[('This is the first line', 'Line1'), ('This is the second line', 'Line2'), ('This is the third line', 'Line3')]
旧的 Python 2 答案,也使用 csv
模块:
import csv
with open('file.csv', 'rb') as f:
reader = csv.reader(f)
your_list = list(reader)
print your_list
# [['This is the first line', 'Line1'],
# ['This is the second line', 'Line2'],
# ['This is the third line', 'Line3']]
【讨论】:
你为什么用'rb'而不是'r'? @DrunkenMaster,b
导致文件以二进制模式而不是文本模式打开。在某些系统上,文本模式意味着\n
在读取或写入时将转换为特定于平台的新行。 See docs.
这在 Python 3.x 中不起作用:“csv.Error:迭代器应该返回字符串,而不是字节(您是否以文本模式打开文件?)”请参阅下面的答案Python 3.x
为了节省几秒钟的调试时间,您可能应该为第一个解决方案添加注释,例如“Python 2.x 版本”
如何使用您的第一个解决方案,但只有 csv 文件中的一些列?【参考方案2】:
为 Python 3 更新:
import csv
with open('file.csv', newline='') as f:
reader = csv.reader(f)
your_list = list(reader)
print(your_list)
输出:
[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
【讨论】:
指定'r'
是默认模式,因此无需指定。文档还提到如果 csvfile 是文件对象,则应使用 newline='' 打开它。
我希望票数最高的答案提到了代码的复制来源。【参考方案3】:
Pandas 非常擅长处理数据。这是一个如何使用它的示例:
import pandas as pd
# Read the CSV into a pandas data frame (df)
# With a df you can do many things
# most important: visualize data with Seaborn
df = pd.read_csv('filename.csv', delimiter=',')
# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]
# or export it as a list of dicts
dicts = df.to_dict().values()
一大优势是 pandas 会自动处理标题行。
如果你还没有听说过Seaborn,我建议你去看看。
另见:How do I read and write CSV files with Python?
熊猫#2
import pandas as pd
# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()
# Convert
dicts = df.to_dict('records')
df的内容是:
country population population_time EUR
0 Germany 82521653.0 2016-12-01 True
1 France 66991000.0 2017-01-01 True
2 Indonesia 255461700.0 2017-01-01 False
3 Ireland 4761865.0 NaT True
4 Spain 46549045.0 2017-06-01 True
5 Vatican NaN NaT True
dicts的内容是
['country': 'Germany', 'population': 82521653.0, 'population_time': Timestamp('2016-12-01 00:00:00'), 'EUR': True,
'country': 'France', 'population': 66991000.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': True,
'country': 'Indonesia', 'population': 255461700.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': False,
'country': 'Ireland', 'population': 4761865.0, 'population_time': NaT, 'EUR': True,
'country': 'Spain', 'population': 46549045.0, 'population_time': Timestamp('2017-06-01 00:00:00'), 'EUR': True,
'country': 'Vatican', 'population': nan, 'population_time': NaT, 'EUR': True]
熊猫#3
import pandas as pd
# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()
# Convert
lists = [[row[col] for col in df.columns] for row in df.to_dict('records')]
lists
的内容是:
[['Germany', 82521653.0, Timestamp('2016-12-01 00:00:00'), True],
['France', 66991000.0, Timestamp('2017-01-01 00:00:00'), True],
['Indonesia', 255461700.0, Timestamp('2017-01-01 00:00:00'), False],
['Ireland', 4761865.0, NaT, True],
['Spain', 46549045.0, Timestamp('2017-06-01 00:00:00'), True],
['Vatican', nan, NaT, True]]
【讨论】:
tuples = [tuple(x) for x in df.values]
可以改为tuples = list(df.itertuples(index=False))
。请注意,Pandas 文档不鼓励使用.values
,而是使用.to_numpy()
。第三个例子让我感到困惑。首先,因为变量名为tuples
,这意味着它是一个元组列表,而它实际上是一个列表列表。其次,因为据我所知,整个表达式可以替换为df.to_list()
。我也不知道第二个例子在这里是否真的相关。【参考方案4】:
Python3 更新:
import csv
from pprint import pprint
with open('text.csv', newline='') as file:
reader = csv.reader(file)
res = list(map(tuple, reader))
pprint(res)
输出:
[('This is the first line', ' Line1'),
('This is the second line', ' Line2'),
('This is the third line', ' Line3')]
如果 csvfile 是一个文件对象,它应该用newline=''
打开。csv module
【讨论】:
为什么在列表理解上使用list(map())
?另外,请注意第二列每个元素开头的空格。【参考方案5】:
如果您确定输入中没有逗号,除了分隔类别,您可以在,
上read the file line by line 和split,然后将结果推送到List
也就是说,您正在查看 CSV 文件,因此您可以考虑使用 the modules
【讨论】:
【参考方案6】:result = []
for line in text.splitlines():
result.append(tuple(line.split(",")))
【讨论】:
您能在这篇文章中添加一些解释吗?仅代码(有时)很好,但代码和解释(大多数时候)更好 我知道 Barranka 的评论已经有一年多的历史了,但是对于任何偶然发现这一点并且无法弄清楚的人:for line in text.splitlines(): puts临时变量“line”中的每一行。 line.split(",") 创建一个以逗号分隔的字符串列表。 tuple(~) 将该列表放入元组中,append(~) 将其添加到结果中。在循环之后,result 是一个元组列表,每个元组代表一行,每个元组元素是 csv 文件中的一个元素。 除了@Louis 说的,没有必要使用.read().splitlines()
,你可以直接遍历文件的每一行:for line in in_file: res.append(tuple(line.rstrip().split(",")))
另外,请注意使用.split(',')
表示第二列的每个元素都以额外的空格开头。
我刚才分享的代码的附录:line.rstrip()
-> line.rstrip('\n')
。【参考方案7】:
一个简单的循环就足够了:
lines = []
with open('test.txt', 'r') as f:
for line in f.readlines():
l,name = line.strip().split(',')
lines.append((l,name))
print lines
【讨论】:
如果某些条目中有逗号怎么办? @TonyEnnis 那么您需要使用更高级的处理循环。上面 Maciej 的回答展示了如何使用 Python 自带的 csv 解析器来执行这个操作。这个解析器很可能拥有你需要的所有逻辑。【参考方案8】:正如在 cmets 中已经说过的,您可以在 python 中使用csv
库。 csv 表示逗号分隔的值,这似乎正是您的情况:标签和用逗号分隔的值。
作为一个类别和值类型,我宁愿使用字典类型而不是元组列表。
无论如何,在下面的代码中,我显示了两种方式:d
是字典,l
是元组列表。
import csv
file_name = "test.txt"
try:
csvfile = open(file_name, 'rt')
except:
print("File not found")
csvReader = csv.reader(csvfile, delimiter=",")
d = dict()
l = list()
for row in csvReader:
d[row[1]] = row[0]
l.append((row[0], row[1]))
print(d)
print(l)
【讨论】:
为什么不使用上下文管理器来处理文件?为什么要混合两种不同的变量命名约定?(row[0], row[1])
不是比只使用tuple(row)
更弱/更容易出错吗?
为什么你认为做 tuple(row) 不太容易出错?你指的是什么变量命名约定?请链接官方 python 命名约定。据我所知,try -except 是处理文件的好方法:上下文处理程序是什么意思?
为什么你认为 tuple(row) 不太容易出错? 因为它不需要你手动写出每个索引。如果你犯了一个错误,或者元素的数量发生了变化,你必须回去修改你的代码。 try-except 很好,上下文管理器是 with 语句。你可以找到很多关于这个主题的资源,比如this one。
我看不出上下文管理器会比 ol' 好的 try-except 块更好。另一方面,积极的方面是您输入的代码更少;其余的,如果元素的数量(我猜你的意思是列的数量)改变我的更好,因为它只提取所需的值,而另一个它正在提取所有的 excel。没有任何具体要求,你不能说哪个更好,所以争论哪个更好是浪费时间:在这种情况下,两者都是有效的
我看不出上下文管理器会比 ol' 好的 try-except 块更好。 请参阅我之前的评论,上下文管理器 会不替换 try-except。【参考方案9】:
不幸的是,我发现没有一个现有答案特别令人满意。
这是一个简单而完整的 Python 3 解决方案,使用 csv 模块。
import csv
with open('../resources/temp_in.csv', newline='') as f:
reader = csv.reader(f, skipinitialspace=True)
rows = list(reader)
print(rows)
注意skipinitialspace=True
参数。这是必要的,因为不幸的是,OP 的 CSV 在每个逗号后都包含空格。
输出:
[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
【讨论】:
【参考方案10】:您可以使用list()
函数将csv阅读器对象转换为列表
import csv
with open('input.csv') as csv_file:
reader = csv.reader(csv_file, delimiter=',')
rows = list(reader)
print(rows)
【讨论】:
【参考方案11】:稍微扩展您的要求并假设您不关心行的顺序并希望将它们分组到类别下,以下解决方案可能适合您:
>>> fname = "lines.txt"
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> with open(fname) as f:
... for line in f:
... text, cat = line.rstrip("\n").split(",", 1)
... dct[cat].append(text)
...
>>> dct
defaultdict(<type 'list'>, ' CatA': ['This is the first line', 'This is the another line'], ' CatC': ['This is the third line'], ' CatB': ['This is the second line', 'This is the last line'])
通过这种方式,您可以获得字典中所有可用的相关行,键为类别。
【讨论】:
【参考方案12】:这是在 Python 3.x 中将 CSV 导入多维数组的最简单方法,并且只需 4 行代码,无需导入任何内容!
#pull a CSV into a multidimensional array in 4 lines!
L=[] #Create an empty list for the main array
for line in open('log.txt'): #Open the file and read all the lines
x=line.rstrip() #Strip the \n from each line
L.append(x.split(',')) #Split each line into a list and add it to the
#Multidimensional array
print(L)
【讨论】:
小心,它是一个列表,而不是一个数组!为什么不使用上下文管理器来正确处理文件对象?请注意,此解决方案会在每行的第二个项目上留下额外的空格,如果任何数据包含逗号,它将失败。【参考方案13】:接下来是一段代码,它使用 csv 模块,但使用第一行(即 csv 表的标题)将 file.csv 内容提取到字典列表中
import csv
def csv2dicts(filename):
with open(filename, 'rb') as f:
reader = csv.reader(f)
lines = list(reader)
if len(lines) < 2: return None
names = lines[0]
if len(names) < 1: return None
dicts = []
for values in lines[1:]:
if len(values) != len(names): return None
d =
for i,_ in enumerate(names):
d[names[i]] = values[i]
dicts.append(d)
return dicts
return None
if __name__ == '__main__':
your_list = csv2dicts('file.csv')
print your_list
【讨论】:
为什么不直接使用csv.DictReader
?以上是关于Python 导入 csv 到列表的主要内容,如果未能解决你的问题,请参考以下文章