【问题标题】:How to find the difference between two lists of dictionaries checking the key-value pair如何找到检查键值对的两个字典列表之间的差异
【发布时间】:2015-09-03 11:30:36
【问题描述】:

我已经在寻找解决问题的方法,但没有成功。我的问题的部分解决方案是here,但这并不能解决所有问题。

我有两个这样的字典列表 - 每个字典都写入一个 csv 文件,但我将内容读取到以下变量:

list1 = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
list2 = [{b:2, a:1, c:3}, {c:6, b:5, a:4}, {b:8, a:7, c:9}]

使用上面链接的解决方案,即:

>>> import itertools

>>> a = [{'a': '1'}, {'c': '2'}]
>>> b = [{'a': '1'}, {'b': '2'}]
>>> intersec = [item for item in a if item in b]
>>> sym_diff = [item for item in itertools.chain(a,b) if item not in intersec]

我没有找到匹配项,因为字典的顺序不同。但实际上,这两个列表是相同的。我怎样才能检查这个?在将字典写入 csv 文件之前,我是否必须对它们进行排序?这可以解决吗?

这是我目前的主要问题,但我还有另一个问题。如果能够进行匹配检查但忽略我定义的一个或多个键,那就太好了。这也可以吗?

编辑:我在 csv 文件中有字典,我正在使用以下代码阅读它们:

def read_csv_file(self, filename):
    '''Read CSV file and return its content as a Python list.'''
    f = open(filename, 'r')
    csvfile = csv.reader(f)
    f.close
    return [row for row in csvfile]

这非常重要,因为我认为问题在于从 csv 读取值后它不再是字典,因此顺序必须相同。

EDIT2:csv 文件的示例(3 行,它正在创建一个空行,但这不是问题...)

"{u'Deletion': '0', u'Source': 'Not Applicable', u'Status': ''}"

"{u'Deletion': '0', u'Source': 'Not Applicable', u'Status': ''}"

【问题讨论】:

  • 你能发布一个你的 csv 文件的例子,看看它是如何格式化的吗?
  • 如果您正在读取此 CSV 文件中的每一行,那么 list2 的用途是什么?
  • 我正在读取两个不同的 csv,然后比较它们。
  • 所以如果我理解得很好,你是从两个 csv 文件中读取并将字典存储在列表中,那么你想得到两个列表之间的差异和交集,对吧?
  • 使用csv.reader()从您的csv文件中读取将返回给您一个字符串列表,而不是字典......!

标签: python list csv dictionary


【解决方案1】:

根据我们上次的 CHAT 对话,OP 发现了这个解决方案的一部分,它是使用 ast 模块将字符串转换为字典。

现在使用此模块转换csv.reader() 读取的每一行,因为它返回一个字符串列表,如果是 OP 的 CVS 文件,这将是一个字符串的列表,然后将此字典附加到一个列表中。之后使用itertools.chain 的列表推导,我们可以得到两个列表之间的差异。

import csv
import ast
import itertools

def csvToList(myCSVFile):

    '''This function is used to convert strings returned by csv.reader() into List of dictionaries'''

        f = open(myCSVFile, 'r')
        l = []
        try:
            reader = csv.reader(f)
            for row in reader:
                if row: #as you mentioned in your 2nd edit that you could have empty rows.
                    l.append(ast.literal_eval(row[0]))
        finally:
            f.close()        
        return l

list1 = csvToList('myCSV1.csv')
list2 = csvToList('myCSV2.csv')

l1_sub_l2  = [d for d in list1 if d not in list2]
l2_sub_l1  = [d for d in list2 if d not in list1]
list_difference = list(itertools.chain(l1_sub_l2, l2_sub_l1))   

【讨论】:

    【解决方案2】:

    您需要仔细检查您的代码。我不明白你提出的问题。

    list1 = [{a:1, b:2, c:3}, {a:4, b:5, c:6}, {a:7, b:8, c:9}]
    list2 = [{b:2, a:1, c:3}, {c:6, b:5, a:4}, {b:8, a:7, c:9}]
    
    list1 = [{'a':1, 'b':2, 'c':3}, {'a':4, 'b':5, 'c':7}, {'a':7, 'b':8, 'c':9}]
    list2 = [{'b':2, 'a':1, 'c':3}, {'c':6, 'b':2, 'a':4}, {'b':8, 'a':7, 'c':9}]
    intersec = [item for item in list1 if item in list2]
    sym_diff = [item for item in itertools.chain(list1,list2) if item not in intersec]
    
    print(intersec)
    print(sym_diff)
    
    >>>[{'a': 1, 'c': 3, 'b': 2}, {'a': 4, 'c': 6, 'b': 5}, {'a': 7, 'c': 9, 'b': 8}]
    >>>>[]
    

    如果我更改 list1 和 list 2(中间字典):

    list1 = [{'a':1, 'b':2, 'c':3}, {'a':7, 'b':5, 'c':2}, {'a':7, 'b':8, 'c':9}]
    list2 = [{'b':2, 'a':1, 'c':3}, {'c':6, 'b':5, 'a':4}, {'b':8, 'a':7, 'c':9}]
    

    运行相同的代码:

    [{'a': 1, 'c': 3, 'b': 2}, {'a': 7, 'c': 9, 'b': 8}]
    [{'a': 7, 'c': 2, 'b': 5}, {'a': 4, 'c': 6, 'b': 5}]
    

    链接中提供的代码似乎工作正常。字典或列表的顺序在 python 中无关紧要。

    【讨论】:

    • 嗨,Leb。我用重要信息编辑了我的问题。我认为在阅读 csv 文件后,我处理的是字符串,而不是字典。所以我现在的问题是我是否可以将其视为字典(以及如果从 csv 读取如何处理),或者保存到 csv 之前的排序是否是一个正确的解决方案。
    【解决方案3】:

    在返回时使用dictionary comprehension 而不是列表推导式。

    【讨论】:

    • 我想我在 Python 中得到了这个工作。不幸的是,我还需要它与 jython 一起工作,它给了我这个错误: java.lang.ClassFormatError: Invalid method Code length 240222 in class file org/python/pycode/_pyx2 java.lang.ClassFormatError: java.lang.ClassFormatError: Invalid类文件org/python/pycode/_pyx2中的方法代码长度240222
    • 我已经设法解决了 Jython 问题,但我仍在为比较而苦苦挣扎。在将字典添加到 csv 之前,我尝试按字母顺序对字典进行排序,但没有成功。
    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多