简体   繁体   English

检查另一个字典中是否存在python字典中值列表中的值

[英]Check if a value from a list of values in a python dictionary exists in another dictionary

I writing a python script to verify report templates. 我编写了一个python脚本来验证报告模板。 There is a master template, which contains all possible reports with all their possible fields. 有一个主模板,其中包含所有可能的报告及其所有可能的字段。 Then there is a template csv which contains some of those reports. 然后有一个模板csv,其中包含一些报告。 For simplicity lets say then look like this; 为简单起见,我们可以说看起来像这样;

Template csv: 模板csv:

OutputName, col1, col2, col3, col4, col5 PersonReport, name, surname, age, dob, id AccountReport, f1, f2, f3, f4, f5 TransactionReport, f1, f2, f3, f4, f5

Master csv: 掌握csv:

OutputName, col1, col2, col3, col4, col5 PersonReport, name, surname, street, age, id TransactionReport, f1, f2, f3, f4, f5

So in this example the AccountReport doesn't even exist in the Master, the PersonReport contains a field dob which isn't valid because it isn't in the Master. 因此,在此示例中, AccountReport甚至不存在于Master中, PersonReport包含一个无效的字段dob ,因为它不在Master中。 The only valid report is TransactionReport . 唯一有效的报告是TransactionReport

So I idea is to read these csvs in as dictionaries, with the OutputName as the key and the field names as the values. 所以我的想法是在字典中读取这些csvs,其中OutputName作为键,字段名称作为值。

 import pandas as pd
 masterDf = pd.read_csv('master.csv')
 master = masterDf.set_index('OutputName').T.to_dict('list')

 templateDf = pd.read_csv('template.csv')
 template = templateDf.set_index('OutputName').T.to_dict('list')

The dictionaries looks like; 字典看起来像;

template = {' PersonReport': [' name', ' surname', ' age', ' dob', ' id'], ' AccountReport': [' f1', ' f2', ' f3', ' f4', ' f5 '], ' TransactionReport': [' f1', ' f2', ' f3', ' f4', ' f5']}

master = {' PersonReport': [' name', ' surname', ' street', ' age', ' id'], ' TransactionReport': [' f1', ' f2', ' f3', ' f4', ' f5']}

Now the I want to first match on the keys, to find out which keys don't exist in the master dict. 现在我想首先匹配键,找出主dict中不存在哪些键。 After that when finding keys that do match, I wish to check if the values in the dictionary are valid, by checking that they exist in the master dict's values. 在找到匹配的键之后,我希望通过检查它们是否存在于主dict的值中来检查字典中的值是否有效。

So I try : 所以我尝试:

errorCount = 0

for key, value in template.items():
    if key  not in master:
        print("{} is an invalid report".format(key))
        errorCount += 1
    if key in master:
        for fields in template.values():
            for field in fields:
                for cols in master.values():
                    if field not in cols:
                        print("{} is an invalid field in {} report".format(field, key))
                        errorCount += 1

However the output I get is wrong. 但是我得到的输出是错误的。 I get : 我明白了:

name is an invalid field in  PersonReport report
 surname is an invalid field in  PersonReport report
 age is an invalid field in  PersonReport report
 dob is an invalid field in  PersonReport report
 dob is an invalid field in  PersonReport report
 id is an invalid field in  PersonReport report
 f1 is an invalid field in  PersonReport report
 f2 is an invalid field in  PersonReport report
 f3 is an invalid field in  PersonReport report
 f4 is an invalid field in  PersonReport report
 f5  is an invalid field in  PersonReport report
 f5  is an invalid field in  PersonReport report
 f1 is an invalid field in  PersonReport report
 f2 is an invalid field in  PersonReport report
 f3 is an invalid field in  PersonReport report
 f4 is an invalid field in  PersonReport report
 f5 is an invalid field in  PersonReport report
 AccountReport is an invalid report
 name is an invalid field in  TransactionReport report
 surname is an invalid field in  TransactionReport report
 age is an invalid field in  TransactionReport report
 dob is an invalid field in  TransactionReport report
 dob is an invalid field in  TransactionReport report
 id is an invalid field in  TransactionReport report
 f1 is an invalid field in  TransactionReport report
 f2 is an invalid field in  TransactionReport report
 f3 is an invalid field in  TransactionReport report
 f4 is an invalid field in  TransactionReport report
 f5  is an invalid field in  TransactionReport report
 f5  is an invalid field in  TransactionReport report
 f1 is an invalid field in  TransactionReport report
 f2 is an invalid field in  TransactionReport report
 f3 is an invalid field in  TransactionReport report
 f4 is an invalid field in  TransactionReport report
 f5 is an invalid field in  TransactionReport report

My expected output would : 我的预期输出将是:

AccountReport is an invalid report
dob is an invalid field in PersonReport report

Any help is appreciated Thanks ps I'm using python 3.6 任何帮助表示赞赏谢谢ps我正在使用python 3.6

You can try this: 你可以试试这个:

template = {' PersonReport': [' name', ' surname', ' age', ' dob', ' id'], ' AccountReport': [' f1', ' f2', ' f3', ' f4', ' f5 '], ' TransactionReport': [' f1', ' f2', ' f3', ' f4', ' f5']}
master = {' PersonReport': [' name', ' surname', ' street', ' age', ' id'], ' TransactionReport': [' f1', ' f2', ' f3', ' f4', ' f5']}
invalid_names = ["{} in dict".format(i) if i in master else "{} not in dict".format(i) for i in template]
invalid_values = filter(lambda x:x, [["{} is an invalid value".format(c) for c in b if c not in master[a]] for a, b in template.items() if a in master])
print(invalid_names)
print(invalid_values)

Output: 输出:

[' TransactionReport in dict', ' PersonReport in dict', ' AccountReport not in dict']
[[' dob is an invalid value']]

Your code had couple of mistakes which lead to you checking every field. 您的代码有几个错误,导致您检查每个字段。 Use of continue and only iterating over the correct key solved this. 使用continue并且只迭代正确的密钥解决了这个问题。 Here's a fixed code snippet: 这是一个固定的代码片段:

for key in template.keys():
    if key not in master:
        print("{} is an invalid report".format(key))
        errorCount += 1
        continue # Continue to next key
    cols = master[key] # Get the correct column names from the current key
    errorFlag = False
    for field in template[key]:
        if field not in cols:
            print("{} is an invalid field in {} report".format(field, key)) 
            errorCount += 1
            errorFlag = True # You can break here if you wish not to keep incrementing the errorCount.

    if not errorFlag: # We did not find any bad column
        print("Success finding valid {} report in master".format(key))

This outputs: 这输出:

 dob is an invalid field in  PersonReport report
 AccountReport is an invalid report
Success finding valid  TransactionReport report in master

I kept it simple and followed your conventions: 我保持简单并遵循您的惯例:

errorCount = 0

for key in template.keys():
    if key not in master:
        print("{} is an invalid report".format(key))
        errorCount += 1
    else:
        if template[key] != master[key]:
            fields = [f for f in template[key] if f not in master[key]]
            for f in fields:
                print("{} is an invalid field in {} report".format(f, key))
                errorCount += 1

From the console: 从控制台:

AccountReport is an invalid report
dob is an invalid field in  PersonReport report

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM