【问题标题】:Join two CSV files in python using dictreader使用 dictreader 在 python 中加入两个 CSV 文件
【发布时间】:2012-02-28 13:46:04
【问题描述】:

我意识到回答这个问题的信息可能已经在这里了,但是作为一个 python 新手,我已经尝试将这些信息拼凑几个星期了,但我遇到了一些麻烦。

这个问题Python "join" function like unix "join" 回答了如何轻松地在两个列表上进行连接,但问题是 dictreader 对象是可迭代的而不是简单的列表,这意味着增加了一层复杂性。

我基本上是在使用 dictreader 对象寻找两个 CSV 文件的内部连接。这是我到目前为止的代码:

def test(dictreader1, dictreader2):
    matchedlist = []
    for dictline1 in dictreader1:
            for dictline2 in dictreader2:
                if dictline1['member']=dictline2['member']:
                    matchedlist.append(dictline1, dictline2)
                else: continue
    return matchedlist

这在 if 语句中给了我一个错误,但更重要的是,我似乎无法在可迭代对象中访问字典的 ['member'] 元素,因为它说它没有属性“ getitem”。

有人对如何做到这一点有任何想法吗?作为参考,我需要将列表保留为可迭代对象,因为每个文件都太大而无法放入内存。计划是在另一个 for 循环中控制整个函数,一次只输入几行以进行迭代。因此它将读取左侧文件的一行,遍历整个第二个文件以找到匹配的成员字段,然后将这两行连接起来,类似于 SQL 连接语句。

提前感谢您的帮助,请原谅我的任何明显错误。

【问题讨论】:

    标签: python database csv


    【解决方案1】:

    一些想法:

    • = 替换为==。后者用于相等性测试;前者用于分配。

    • 在开头添加一行dictreader2 = list(dictreader2)。这样就可以多次循环遍历字典条目。

    • 将第二对括号添加到matchedlist.append((dictline1, dictline2))list.append 方法只接受一个参数,因此您想从 dictline1dictline2 创建一个元组。

      李>
    • 最后的else: continue 是不必要的。一个for循环会自动为你循环。

    • 使用打印语句或类似语句来验证 dictline1dictline2 是否都是以 member 作为键的字典对象。可能是您的函数是正确的,但被调用的不是 dictreader 对象。

    这是一个使用 dicts 列表作为输入的示例(类似于 DictReader 将返回的内容):

    >>> def test(dictreader1, dictreader2):
            dictreader2 = list(dictreader2)
            matchedlist = []
            for dictline1 in dictreader1:
                for dictline2 in dictreader2:
                    if dictline1['member'] == dictline2['member']:
                        matchedlist.append((dictline1, dictline2))
            return matchedlist
    
    >>> dr1 = [{'member': 2, 'value':'abc'}, {'member':3, 'value':'def'}]
    >>> dr2 = [{'member': 4, 'tag':'t4'}, {'member':3, 'tag':'t3'}]
    >>> test(dr1, dr2)
    [({'member': 3, 'value': 'def'}, {'member': 3, 'tag': 't3'})]
    

    进一步的建议是将两个字典合并到一个条目中(这更接近 SQL 内连接所做的):

    >>> def test(dictreader1, dictreader2):
            dictreader2 = list(dictreader2)
            matchedlist = []
            for dictline1 in dictreader1:
                for dictline2 in dictreader2:
                    if dictline1['member'] == dictline2['member']:
                        entry = dictline1.copy()
                        entry.update(dictline2)
                        matchedlist.append(entry)
            return matchedlist
    
    >>> test(dr1, dr2)
    [{'member': 3, 'tag': 't3', 'value': 'def'}]
    

    祝你的项目好运:-)

    【讨论】:

    • 非常感谢,效果很好!我认为我的一个问题是我在将两个 dictreaders 传递给函数之前打印了它们,这似乎在迭代器被函数读取之前就已经用尽了它......现在我只需要想出一种方法来重置它。也感谢您提供有关更新字典的提示,这是一种更好的方法!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 2017-10-19
    相关资源
    最近更新 更多