【问题标题】:Python import csv to listPython 导入 csv 到列表
【发布时间】: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 导入我需要的列表?

【问题讨论】:

标签: python csv


【解决方案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 linesplit,然后将结果推送到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
          猜你喜欢
          • 2012-12-31
          • 2018-05-06
          • 2017-07-20
          • 2019-11-09
          • 2022-01-03
          • 2013-11-04
          • 1970-01-01
          相关资源
          最近更新 更多