Цикл поиска соответствующих значений в двух словарях - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть два разных файла, которые состоят из словарей.Я пытаюсь перебрать только ключ ('name'), значение в первом файле словарей и сопоставить их со вторым файлом.Я, кажется, получаю неправильный вывод, поскольку он проходит через оба ключа 'name' и 'size'.Я рассмотрел несколько способов сделать это, но я не хочу, чтобы иметь возможность преобразовать свой словарь в набор.Я хочу, чтобы можно было распечатать либо «соответствует» или «не соответствует».До сих пор я сделал следующее:

def compare_files():

with open('new.json', 'r') as current_data_file, open('old.json','r') as pre_data_file:

    for current_data, previous_data in zip(current_data_file, pre_data_file):

        data_current = json.loads(current_data)
        data_previous = json.loads(previous_data)



        for key, value in data_current.items():
            if value not in data_previous:
                print "No Match"
            else:
                print "Match"

Это мои два файла json, которые я загружаю:

old.json

{"name": "d.json", "size": 1000}
{"name": "c.json", "size": 1000}
{"name": "b.json", "size": 1000}

new.json

{"name": "a.json", "size": 1000}
{"name": "b.json", "size": 1000}
{"name": "c.json", "size": 1000}

data_current:

{u'size': 1000, u'name': u'a.json'}
{u'size': 1000, u'name': u'b.json'}
{u'size': 1000, u'name': u'c.json'}

data_previous is:

{u'size': 1000, u'name': u'd.json'}
{u'size': 1000, u'name': u'c.json'}
{u'size': 1000, u'name': u'b.json'}

Вывод:

No Match
No Match
No Match
No Match
No Match
No Match

Мой ожидаемый вывод:

No Match
Match
Match

b.json и c.json существуют в обоих, а a.json и d.json - нет.

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Вы для каждого «текущего» предмета должны сравнивать со всеми «предыдущими» предметами, а не только с тем, который находится в той же позиции (что и поможет вам достичь «zip»)

data_current = [{"name": "d.json", "size": 1000},
                {"name": "c.json", "size": 1000},
                {"name": "b.json", "size": 1000}]

data_previous = [{"name": "a.json", "size": 1000},
                 {"name": "b.json", "size": 1000},
                 {"name": "c.json", "size": 1000}]

for current in data_current:
    result = "No Match"
    for previous in data_previous:
        if current["name"] == previous["name"]:
            result = "Match"
    print(result)

РЕДАКТИРОВАТЬ: Если вы хотите проверить элементы текущего против предыдущего, а также предыдущего против текущего, вы можете сделать следующее (я добавил текст к отпечаткам, чтобы прояснить, что происходит)

checks_to_run = [
    {
        "from": data_current,
        "from_name": "current", #Added for transparency
        "against": data_previous,
        "against_name": "previous", #Added for transparency
    },
    {
        "from": data_previous,
        "from_name": "previous", #Added for transparency
        "against": data_current,
        "against_name": "current", #Added for transparency
    }
]

for check_to_run in checks_to_run:
    for check_from in check_to_run["from"]:
        result = "No Match"
        for check_against in check_to_run["against"]:
            if check_from["name"] == check_against["name"]:
                result = "Match"
        print("result for item {} from {} compared to items in {}: {}".format(check_from["name"],
                                                                              check_to_run["from_name"],
                                                                              check_to_run["against_name"],
                                                                              result))
0 голосов
/ 12 декабря 2018

Чтобы уберечься от неприятностей, вы можете напрямую читать данные, используя pandas (сторонняя библиотека), и можете очень легко выполнить анализ

import pandas as pd

df=pd.DataFrame('new.json')
df2=pd.DataFrame('old.json')

df.name.isin(df2.name).replace({False:'No Match',True:'Match'}).tolist()

Вывод

['No Match', 'Match', 'Match']
0 голосов
/ 12 декабря 2018

В вашем коде есть пара проблем.

  1. Когда вы делаете if value not in data_previous:, вы фактически проверяете, есть ли value в клавишах из data_previous, а не в его значениях.

  2. Когда вы делаете zip(current_data_file, pre_data_file), вы на самом деле смотрите на соответствующие пары двух словарей.Здесь у вас есть 3 словаря с 2 ключами в каждом, поэтому у вас есть 6 выходных строк вместо 3. Другими словами, вы просматриваете данные попарно, а не сравниваете каждый словарь в данных со всеми остальными в другомданные.

Вот пример кода:

def compare_files():
    with open('new.json', 'r') as current_data_file, open('old.json','r') as pre_data_file:
        # load both data 
        data_currents = [json.loads(line) for line in current_data_file]
        data_previous = [json.loads(line) for line in pre_data_file]

        # store the previous names for convenient lookup
        pre_names = set([data["name"] for data in data_previous])

        # loop through all current data for matching names
        for data in data_currents:
            print("Match" if data["name"] in pre_names else "No Match")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...