【问题标题】:Reading csv file and returning as dictionary读取 csv 文件并作为字典返回
【发布时间】:2017-03-26 22:58:53
【问题描述】:

我编写了一个当前可以正确读取文件的函数,但存在一些问题。它需要作为字典返回,其中键是艺术家姓名,值是元组列表(对此不确定,但这似乎是它的要求)

我遇到的主要问题是我需要以某种方式跳过文件的第一行,并且我不确定是否将其作为字典返回。以下是其中一个文件的示例:

"Artist","Title","Year","Total  Height","Total  Width","Media","Country"
"Pablo Picasso","Guernica","1937","349.0","776.0","oil  paint","Spain"
"Vincent van Gogh","Cafe Terrace at Night","1888","81.0","65.5","oil paint","Netherlands"
"Leonardo da Vinci","Mona Lisa","1503","76.8","53.0","oil paint","France"
"Vincent van Gogh","Self-Portrait with Bandaged Ear","1889","51.0","45.0","oil paint","USA"
"Leonardo da Vinci","Portrait of Isabella d'Este","1499","63.0","46.0","chalk","France"                
"Leonardo da Vinci","The Last Supper","1495","460.0","880.0","tempera","Italy"

所以我需要读取一个输入文件并将其转换成一个如下所示的字典:

sample_dict = {
        "Pablo Picasso":    [("Guernica", 1937, 349.0,  776.0, "oil paint", "Spain")],
        "Leonardo da Vinci": [("Mona Lisa", 1503, 76.8, 53.0, "oil paint", "France"),
                             ("Portrait of Isabella d'Este", 1499, 63.0, 46.0, "chalk", "France"),
                             ("The Last Supper", 1495, 460.0, 880.0, "tempera", "Italy")],
        "Vincent van Gogh": [("Cafe Terrace at Night", 1888, 81.0, 65.5, "oil paint", "Netherlands"),
                             ("Self-Portrait with Bandaged Ear",1889, 51.0, 45.0, "oil paint", "USA")]
      }

我遇到的主要问题是跳过显示“艺术家”、“标题”等的第一行,只返回第一行之后的行。我也不确定我当前的代码是否将其作为字典返回。这是我目前所拥有的

def convertLines(lines):
    head = lines[0]
    del lines[0]
    infoDict = {}
    for line in lines: #Going through everything but the first line
        infoDict[line.split(",")[0]] = [tuple(line.split(",")[1:])]
    return infoDict

def read_file(filename):
    thefile = open(filename, "r")
    lines = []
    for i in thefile:
        lines.append(i)
    thefile.close()
    mydict = convertLines(read_file(filename))
    return lines

对我的代码进行一些小的更改会返回正确的结果,还是我需要以不同的方式处理这个问题?看来我当前的代码确实读取了完整的文件,但是如果还没有,我将如何跳过第一行并可能以 dict 表示形式返回?感谢您的帮助

【问题讨论】:

    标签: python file python-3.x csv dictionary


    【解决方案1】:

    我们要做的第一件事是删除列表的第一行。

    然后我们运行一个函数来完全按照你说的做,用元组列表作为值创建一个字典。

    您可以保留您拥有的函数并在行变量上运行此操作。

    好吧,运行下面的代码,你应该就好了

    def convertLines(lines):
        head = lines[0]
        del lines[0]
        infoDict = {}
        for line in lines: #Going through everything but the first line
            infoDict[line.split(",")[0]] = [tuple(line.split(",")[1:])]
        return infoDict
    
    def read_file(filename):
        thefile = open(filename, "r")
        lines = []
        for i in thefile:
            lines.append(i)
        thefile.close()
        return lines
    
    mydict = convertLines(read_file(filename))
    print(mydict)
    #Do what you want with mydict below this line
    

    【讨论】:

    • 这给了我一个类型错误 'str' 对象不支持删除项目,我应该将其转换为 int 吗?
    • 你在函数中传递了什么?
    • csv 文件我相信我可以使用 open(filename, 'r') as f 读取所有这些文件:我会尝试将其添加到您的代码中
    • 当你运行你拥有的函数时,你会得到一个返回的行数组。执行mydict = convertLines(read_file(filename)) 之类的操作,它应该可以工作
    • 对不起,这太难了,但现在它说 RecursionError:超出了最大递归深度。我更新了上面的代码以显示我是如何运行代码的
    【解决方案2】:

    你应该试试这个。我发现它很简单

    import csv
    from collections import defaultdict
    
    d_dict = defaultdict(list)
    with open('file.txt') as f:
        reader = csv.reader(f)
        reader.next()
        for i in list(reader):
            d_dict[i[0]].append(tuple(i[1:]))
    
    print dict(d_dict)
    

    输出:

    {
      'Vincent van Gogh': [
        ('Cafe Terrace at Night', '1888', '81.0', '65.5', 'oil paint', 'Netherlands'),
        ('Self-Portrait with Bandaged Ear', '1889', '51.0', '45.0', 'oil paint', 'USA')
      ],
      'Pablo Picasso': [
        ('Guernica', '1937', '349.0', '776.0', 'oil  paint', 'Spain')
      ],
      'Leonardo da Vinci': [
        ('Mona Lisa', '1503', '76.8', '53.0', 'oil paint', 'France'),
        ("Portrait of Isabella d'Este", '1499', '63.0', '46.0', 'chalk', 'France'),
        ('The Last Supper', '1495', '460.0', '880.0', 'tempera', 'Italy')
      ]
    }
    

    【讨论】:

    • 由于某种原因,我收到 print dict(d_dict) 的无效语法错误
    • 什么是'print d_dict'?
    • 由于语法错误,没有打印任何内容
    • 对不起,我刚刚意识到你要求用 print d_dict 一秒钟尝试一下
    • 我用我提供的代码在上面发布了我的输出。
    【解决方案3】:

    csv 模块为处理 CSV 文件提供了有用的工具。应该这样做:

    import csv
    from collections import defaultdict
    
    def read_file(filename):
        with open(filename, 'r') as f:
            reader = csv.DictReader(f, delimiter=',')
            result_dict = defaultdict(list)
            fields = ("Title", "Year", "Total  Height", "Total  Width", "Media", "Country")
            for row in reader:
                result_dict[row['Artist']].append(
                    tuple(row[field] for field in fields)
                )
        return dict(result_dict)
    

    DictReader 使用文件第一行中的字段作为字段名称。然后它返回一个对文件中行的迭代,这些行产生为dicts,字段名称作为键。

    【讨论】:

    • What could "Diff is x characters long. Set self.maxDiff to None to see it."意思是?我想我会看到如何将其设置为无。它肯定会正确读取每个文件,这就是为什么我将 x 个字符放长,每个文件的数量不同
    • 我相信我在运行 python testerp.py functions.py 文件时正在运行单元测试。当我在 unittest 中将 maxdiff 设置为 none 时,它​​显示 +、-、- 等字符出现,并且输出中似乎有大量空格和多余的行
    • 好的,这个问题似乎超出了这个线程的范围。
    【解决方案4】:

    更好的做法是:

        with open('filename','r,') as file: # Make a file object
            items = []
            _ = file.readline()  # This will read the first line and store it in _  
                                 # a variable of no use. 
            for line in file:    # Next we start the for loop to read all other  
                                 # data
                item.append(line)
    

    一旦执行此代码,with 语句将关闭文件对象。所以不需要做 f.close()

    【讨论】:

    • 另一种方式它到“文件”上的读取行,然后开始循环。
    • 感谢您的建议,出于某种原因我收到错误“_io.TextIOWrapper”对象不可下标
    • 你知道为什么这会给出错误'builtin_function_or_method' object is not subscriptable吗?这个功能肯定比我想象的要难编程
    • 确实不能像一般列表那样调用文件对象。所以 f[1:] 不起作用。我已经更新了上面的代码。第一个 file.readline() 将文件对象推进到下一行。所以第2行。然后你可以启动for循环来读取文件的其余部分。
    猜你喜欢
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多