从没有模块的csv文件中读取内容

时间:2019-06-04 17:22:08

标签: python

如何在没有csv模块或其他模块的情况下读取.csv文件?我有2个带有电影名称和演员的文件可供阅读。用户需要输入名称并返回该电影中的所有演员。没有任何模块,有可能吗?

文件: all_movies.csv https://dox.abv.bg/download?id=960cefd34e

all_people.csv https://dox.abv.bg/download?id=13c9a04273

all_casts.csv https://dox.abv.bg/download?id=9fa805b24b

3 个答案:

答案 0 :(得分:1)

是的,您可以在不使用任何模块的情况下读入这些csv文件,但是这比使用csvpandas或类似模块更难。我会在这里给您一些想法,但是由于您没有显示自己的代码,因此我不会显示自己的代码。如果您需要代码,请尝试此处的一些操作,并让我们知道您尝试了什么。

您的第一步是了解您想做什么。您的用户界面是什么?如果用户键入多个电影使用的名称怎么办?电影或有多个名字(别名)的人呢?依此类推。

第二步是了解您拥有的数据。例如,all_movies.csv确实是一个逗号分隔的文件。我相信每一行都是文本,我相信采用UTF-8编码-有些电影名称使用希伯来语或阿拉伯语。这些行由换行符(无回车符)分隔。每行有四个字段。每个字段都用双引号引起来,但值\N似乎是空标记。这些字段由单个逗号分隔,没有空格。第一行是标题,其中包含字段名称:"id","name","parent_id","date"。您需要前两个字段:每个电影的唯一ID(以十进制形式的正整数形式给出)和名称(可能不是唯一的)。

下一步是确定数据结构,这些结构将使您可以合理地使用时间和内存来获得所需的内容。例如,您可能需要一个字典,其中每个键都是电影名称,其对应值是具有该名称的电影的ID列表。 (最好使用defaultdict,但是需要collections模块。)您可能不需要all_movies.csv文件中的其他两个字段。您还需要一个词典,其关键字是电影ID,值是电影中人物的人物ID列表,以及一个字典,其关键字是人物ID,值是人物名称,以及其他有关人物的数据。

在解决了这些决定之后(至少是暂时的决定),您可以开始对读取电影文件并创建名称到电影ID字典的例程进行编码。您首先打开文本文件,然后检查标题的第一行作为健全性检查。然后针对每一行尝试执行此操作:

  • 检查该行的第一个字符是否为双引号。如果不是,请将其作为坏行删除。
  • 搜索已找到的第一个双引号字符。您可以使用Python的find()字符串方法,并使用start选项跳过已找到的双引号。
  • 确保两个双引号之间的文本均为十进制数字,然后转换为int值。
  • 确保最后一个双引号后面的两个字符是逗号,然后是另一个双引号。
  • 找到下一个双引号。当双引号前面的字符是反斜杠\时,请将\"转换为"并搜索下一个双引号字符。这是必需的,因为某些电影名称包含双引号,该双引号在文件中以\"的形式转义。例如Making Frankensense of \"Young Frankenstein\",其ID为3161。
  • 将第三和第四双引号之间的文本保存为电影名称。
  • 忽略行的其余部分(可能)。
  • 使用电影名称和ID来创建具有该名称的新字典键(如果需要),然后将ID附加到电影ID列表中。

以此类推。你有主意吗?由于某些电影名称包含逗号(例如,ID为9的Sonntag, im August),因此您不能仅在文本行上用逗号分隔,这是当前两个答案的作用。您需要用双引号引起来。我上面写的另一种方法是split在双引号字符上的行,然后检查结果字段列表,但是转义的双引号和\N空标记将使这变得困难。

我要研究的另一种替代方法是编写一个仅扫描一个字段的例程。它将在null字段和其他字段之间进行区分,所有其他字段都以双引号开头和结尾。那将比我上面概述的要慢,但是可以用来读取其他两个csv文件。如果您展示自己的作品,我可以展示实现此目的的代码。

答案 1 :(得分:0)

就像解析文本文件一样解析它

with open('file.csv', 'r') as f:
    for line in f.read().splitlines():
        data = line.split(',')

答案 2 :(得分:0)

作为生成器:

def readCSV(filepath, separator, header=false):
    with open(filepath, "r") as f:
        if header:
            yield next(f)
        for l in f:
            yield l.split(separator)

文件路径是要读取的文件,分隔符是要与之拆分的令牌,标头是将初始行作为标头返回的标志。

作为示例通话:

data = list(readCSV("file.csv", ";"))