Python将整数从csv文件读入列表

Posted

技术标签:

【中文标题】Python将整数从csv文件读入列表【英文标题】:Python reading in integers from a csv file into a list 【发布时间】:2018-05-07 12:42:34 【问题描述】:

我在尝试将 csv 文件中的特定列读入 Python 列表时遇到了一些麻烦。以下是我的 csv 文件的示例:

Col 1       Col 2
1,000,000   1
  500,000   2
  250,000   3

基本上,我想将第 1 列作为整数值添加到列表中,这样做有很多麻烦。我试过了:

for row in csv.reader(csvfile):
    list = [int(row.split(',')[0]) for row in csvfile]

但是,我收到一个 ValueError,上面写着“invalid literal for int() with base 10: '”1'

然后我尝试了:

for row in csv.reader(csvfile):
    list = [(row.split(',')[0]) for row in csvfile]

这次我没有收到错误,但是我得到了列表:

['"1', '"500', '"250']

我也尝试过更改分隔符:

for row in csv.reader(csvfile):
    list = [(row.split(' ')[0]) for row in csvfile]

这几乎给了我想要的列表,但是该列表包括第二列以及每个值后面的“\n”:

['"1,000,000", 1\n', etc...]

如果有人能帮我解决这个问题,将不胜感激!

干杯

【问题讨论】:

请发布您的 CSV 文件(或只是链接到它),以便我们产生相同的结果。 分隔符是逗号,会是这个问题吗? 如果您的数据中包含逗号,则不能使用逗号作为分隔符 刚刚注意到这是一个很好的问题,所以 +1! 如果只用row[0] 替换row.split(',')[0] 会怎样? csv.reader 已经将逗号分开 【参考方案1】:

您应该明智地选择分隔符: 如果你有使用.的浮点数,使用,分隔符,或者如果你使用,作为浮点数,使用;作为分隔符。

此外,正如the doc for csv.reader 所指,您可以使用delimiter= 参数来定义分隔符,如下所示:

with open('myfile.csv', 'r') as csvfile:
    mylist = []
    for row in csv.reader(csvfile, delimiter=';'):
        mylist.append(row[0]) # careful here with [0]

或短版:

with open('myfile.csv', 'r') as csvfile:
    mylist = [row[0] for row in csv.reader(csvfile, delimiter=';')]

要将您的数字解析为浮点数,您必须这样做

 float(row[0].replace(',', ''))

【讨论】:

他在 csv 标头中有空格 虽然它不是真正的浮点数,但如果没有额外的步骤,浮点数不会真正解析像 1,000,000 这样的东西。 空格实际上是错误的,如果您不使用逗号或分号,制表符是最明智的选择。理论上您可以使用任何空格,但如果这样做,处理包含空格的字符串会变得复杂。无论如何,你应该引用你的字符串。【参考方案2】:

您可以使用正则表达式打开文件并在空格处拆分:

import re
file_data = [re.split('\s+', i.strip('\n')) for i in open('filename.csv')]
final_data = [int(i[0]) for i in file_data[1:]]

【讨论】:

是的。当您拥有专门为读取 csv 构建的整个特殊库时,没有理由做奇怪的正则表达式。【参考方案3】:

首先,您必须正确解析数据。因为它实际上不是 CSV(逗号分隔值)而是 TSV(制表符分隔),您应该通知 CSV 阅读器(我假设它是制表符,但理论上您可以通过一些调整使用任何空格):

for row in csv.reader(csvfile, delimiter="\t"):

其次,您应该去掉任何逗号的整数值,因为它们不会添加新信息。之后,它们可以很容易地用int()解析:

int(row[0].replace(',', ''))

第三,你真的不应该重复同一个列表两次。要么使用列表理解普通for循环,而不是同时使用相同的变量。例如,使用列表推导:

csvfile = StringIO("Col 1\tCol 2\n1,000,000\t1\n500,000\t2\n250,000\t3\n")
reader = csv.reader(csvfile, delimiter="\t")
next(reader, None)  # skip the header
lst = [int(row[0].replace(',', '')) for row in reader]

或正常迭代:

csvfile = StringIO("Col 1\tCol 2\n1,000,000\t1\n500,000\t2\n250,000\t3\n")
reader = csv.reader(csvfile, delimiter="\t")
lst = []
for i, row in enumerate(reader):
    if i == 0:
        continue  # your custom header-handling code here
    lst.append(int(row[0].replace(',', '')))

在这两种情况下,lst 都应设置为 [1000000, 500000, 250000]。享受吧。

顺便说一句,使用保留关键字list 作为变量是一个非常糟糕的主意。

更新。还有一个我觉得有趣的选择。您可以使用csv.Sniffer 来检测它,而不是显式设置分隔符,例如:

csvdata = "Col 1\tCol 2\n1,000,000\t1\n500,000\t2\n250,000\t3\n"
csvfile = StringIO(csvdata)
dialect = csv.Sniffer().sniff(csvdata)
reader = csv.reader(csvfile, dialect=dialect)

然后就像上面的 sn-ps 一样。即使您将制表符替换为分号或逗号(需要在奇怪的整数周围加上引号)或其他可能的东西,这也将继续工作。

【讨论】:

以上是关于Python将整数从csv文件读入列表的主要内容,如果未能解决你的问题,请参考以下文章

如何将 csv 文件读入 SWI prolog 中的列表列表,其中内部列表代表 CSV 的每一行?

python怎么读取csv文件

将csv文件作为python中的变量读入

将 Python 列表写入 csv 文件

Python 导入 csv 到列表

将多个 CSV 文件读入单独的数据帧