Как сравнить python словари по заданному ключу c - PullRequest
0 голосов
/ 07 января 2020

У меня есть файлы данных json и xml, которые возвращают мне данные учетной записи клиента. Они оба имеют почти одинаковые данные, и я должен это проверить. Может иметь одну учетную запись или несколько. Я сделал словарь выбранных ключей, которые мне нужно проверить. Мне нужна помощь:

1) Хранение нескольких словарей где-нибудь, чтобы я мог их сравнить.

2) И способ их сравнения.

Я предоставляю образец Файл данных, содержащий несколько учетных записей.

rest = {
  "ReqType": "CRI",
  "ReqUID": "1234567",
  "ResultCode": "00",
  "Message": "Success",
  "Records": 2,
  "OutData": [
    {
      "CNIC": "123456789",
      "PSTS": "P",
      "CUSTNO": "CHO7SM",
      "Accounts": {
        "NoAccounts": "1",
        "AccountList": [
          {
            "ACC#": "17327901207",
            "TITLE": "John",
            "TYPE": "C",
            "STYPE": "C4",
            "STPDESC": "ACCOUNT CURRENT",
            "REL": "N",
            "LBAL": "2500000",
            "ABAL": "2500000",
            "DECEASED": "N",
            "BLOCKED": "N",
            "INACTIVE": "N",
            "CLOSED": "N"
          }
        ]
      }
    },
    {
      "CNIC": "123456789",
      "PSTS": "S",
      "CUSTNO": "CDG1R8",
      "Accounts": {
        "NoAccounts": "1",
        "AccountList": [
          {
            "ACC#": "17327900081",
            "TITLE": "John",
            "TYPE": "C",
            "STYPE": "C4",
            "STPDESC": "ACCOUNT CURRENT",
            "REL": "N",
            "LBAL": "3486039",
            "ABAL": "3486039",
            "DECEASED": "N",
            "BLOCKED": "N",
            "INACTIVE": "N",
            "CLOSED": "N"
          }
        ]
      }
    }
  ]
}

xml = <?xml version="1.0" encoding="UTF-8"?>
<FCDB_RES_ENV>
    <FCDB_HEADER>
        <SOURCE>FCAT</SOURCE>
        <SERVICE>CustomerAccountsDetails</SERVICE>
        <OPERATION>CustomerAccountsDetails</OPERATION>
        <SOURCE_USERID>FCAT</SOURCE_USERID>
        <DESTINATION>FCDB</DESTINATION>
        <COUNTRYCODE>T001</COUNTRYCODE>
        <USERTYPE>ENS</USERTYPE>
        <LANGID>eng</LANGID>
        <CHANNELID>01</CHANNELID>
    </FCDB_HEADER>
    <FCDB_BODY>
        <CUSTACCOUNT>
            <CUSTNO>
                <CUSTNO>123456789</CUSTNO>
                <TYPECUST>C</TYPECUST>
                <NAMCUST>John</NAMCUST>
                <ADDRESS>
                    <ADDRESS1>ABC.</ADDRESS1>
                </ADDRESS>
            </CUSTNO>
            <ACCOUNT>
                <CUSTNO>123456789</CUSTNO>
                <ACCNO>17327901207</ACCNO>
                <ACCOUNTTITLE>John</ACCOUNTTITLE>
                <ACCOUNTTYPEDETAIL>C4</ACCOUNTTYPEDETAIL>
                <BALANCE>25000.00</BALANCE>
                <ACCTTYPE>C</ACCTTYPE>
                <ACCPRD>AAAA</ACCPRD>
                <ACCPRDDESC>ACCOUNT CURRENT</ACCPRDDESC>
                <ACCCCY>PKR</ACCCCY>
                <STATUS>A</STATUS>
                <RELATION>J</RELATION>
                <BAL_AVAIL>25000.00</BAL_AVAIL>
                <HASCHEQUE>true</HASCHEQUE>
                <HASOVERDRAFT>N</HASOVERDRAFT>
                <UNCLEARFUND>0.00</UNCLEARFUND>
            </ACCOUNT>
            <ACCOUNT>
                <CUSTNO>123456789</CUSTNO>
                <ACCNO>17327900081</ACCNO>
                <ACCOUNTTITLE>John</ACCOUNTTITLE>
                <ACCOUNTTYPEDETAIL>C4</ACCOUNTTYPEDETAIL>
                <BALANCE>34860.39</BALANCE>
                <ACCTTYPE>C</ACCTTYPE>
                <ACCPRD>AAAA</ACCPRD>
                <ACCPRDDESC>ACCOUNT CURRENT</ACCPRDDESC>
                <ACCCCY>PKR</ACCCCY>
                <STATUS>A</STATUS>
                <RELATION>J</RELATION>
                <BAL_AVAIL>34860.39</BAL_AVAIL>
                <HASCHEQUE>true</HASCHEQUE>
                <HASOVERDRAFT>N</HASOVERDRAFT>
                <UNCLEARFUND>0.00</UNCLEARFUND>
            </ACCOUNT>
            <ACCOUNT>
                <CUSTNO>123456789</CUSTNO>
                <ACCNO>17327900940</ACCNO>
                <ACCOUNTTITLE>Adam</ACCOUNTTITLE>
                <ACCOUNTTYPEDETAIL>C4</ACCOUNTTYPEDETAIL>
                <BALANCE>2004976.00</BALANCE>
                <ACCTTYPE>C</ACCTTYPE>
                <ACCPRD>AAAA</ACCPRD>
                <ACCPRDDESC>ACCOUNT CURRENT</ACCPRDDESC>
                <ACCCCY>PKR</ACCCCY>
                <STATUS>A</STATUS>
                <RELATION>J</RELATION>
                <BAL_AVAIL>2004976.00</BAL_AVAIL>
                <HASCHEQUE>true</HASCHEQUE>
                <HASOVERDRAFT>N</HASOVERDRAFT>
                <UNCLEARFUND>0.00</UNCLEARFUND>
            </ACCOUNT>
        </CUSTACCOUNT>
        <FCDB_ERROR_RESP>
            <ERROR>
                <ECODE>00</ECODE>
                <EDESC>Your transaction has been processed successfully.</EDESC>
            </ERROR>
        </FCDB_ERROR_RESP>
    </FCDB_BODY>
</FCDB_RES_ENV>

Я преобразовал ответ soap в словарь, чтобы легко получить элементы.

import json
import xmltodict
from collections import OrderedDict

rest_file = json.loads(rest.read())
doc = xmltodict.parse(xml.read())
input_dict = OrderedDict(doc)
xml_file = json.loads(json.dumps(input_dict))

a = xml['FCDB_RES_ENV']['FCDB_BODY']['CUSTACCOUNT']
for i in a.__getitem__('ACCOUNT'):
    xml_dict = {key: a[key] for key in a if key in ['ACCNO', 'ACCOUNTTITLE', 'ACCOUNTTYPEDETAIL', 'ACCPRDDESC']}
    print(soap_dict)
print("--------------------")

for item in rest.get('OutData'):
    b = (item.get('Accounts')['AccountList'])
    json_file_account = b.pop()

    rest_dict = {key: json_file_account[key] for key in json_file_account if key in
                 ['ACC#', 'TITLE', 'STYPE', 'STPDESC']}
    print(rest_dict)

Вывод приведенного выше сценария:

{'ACCNO': '17327901207', 'ACCOUNTTITLE': 'John', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'}
{'ACCNO': '17327900081', 'ACCOUNTTITLE': 'John', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'}
{'ACCNO': '17327900940', 'ACCOUNTTITLE': 'Adam', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'}
--------------------
{'ACC#': '17327901207', 'TITLE': 'John', 'STYPE': 'C4', 'STPDESC': 'ACCOUNT CURRENT'}
{'ACC#': '17327900081', 'TITLE': 'John', 'STYPE': 'C4', 'STPDESC': 'ACCOUNT CURRENT'}

Для сравнения мне нужно перебрать первый словарь xml в остаток и посмотреть, соответствует ли AccNo, затем сравнить все значения. Любая помощь будет оценена. Спасибо

Ответы [ 2 ]

0 голосов
/ 07 января 2020

Сначала вам нужно добавить все dict в список, а затем перебрать его и сопоставить со значением счетов.

Ниже приведен модифицированный код.

import json
import xmltodict
from collections import OrderedDict

rest_file = json.loads(rest.read())
doc = xmltodict.parse(xml.read())
input_dict = OrderedDict(doc)
xml_file = json.loads(json.dumps(input_dict))
soap_dict_list = []
a = xml['FCDB_RES_ENV']['FCDB_BODY']['CUSTACCOUNT']
for i in a.__getitem__('ACCOUNT'):
    xml_dict = {key: a[key] for key in a if key in ['ACCNO', 'ACCOUNTTITLE', 'ACCOUNTTYPEDETAIL', 'ACCPRDDESC']}
    print(soap_dict)
    soap_dict_list.append(soap_dict)
print(soap_dict_list)
print("--------------------")
rest_dict_list = []
for item in rest.get('OutData'):
    b = (item.get('Accounts')['AccountList'])
    json_file_account = b.pop()

    rest_dict = {key: json_file_account[key] for key in json_file_account if key in
                 ['ACC#', 'TITLE', 'STYPE', 'STPDESC']}
    print(rest_dict)
    rest_dict_list.append(rest_dict)
print(rest_dict_list)

# Now iterate over list
for info1 in rest_dict_list:
    for info2 in soap_dict_list:
        if info1['ACC#'] == info2['ACCNO']:
            print("Account number Match found")
            if info1['TITLE'] == info2['ACCOUNTTITLE']:
                print("ACCOUNTTITLE and TITLE matched")
            # and so on you can match rest of values

0 голосов
/ 07 января 2020

Али Кхан,

1.) Я бы предложил сгруппировать их, используя только ключи, поскольку ключи, похоже, различаются по спискам.

2.) После завершения группировки попробуйте использовать пакет сравнения pandas Dataframe.

Ниже приведен мой код для сравнения всех этих значений.

import pandas as pd

df_struct = list()

df_struct.append({'ACCNO': '17327901207', 'ACCOUNTTITLE': 'John', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'})
df_struct.append({'ACCNO': '17327900081', 'ACCOUNTTITLE': 'John', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'})
df_struct.append({'ACCNO': '17327900940', 'ACCOUNTTITLE': 'Adam', 'ACCOUNTTYPEDETAIL': 'C4', 'ACCPRDDESC': 'ACCOUNT CURRENT'})

df = pd.DataFrame(df_struct)
print(df[df['ACCNO'].duplicated()])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...