Сравните два списка словарей в Python - PullRequest
1 голос
/ 04 ноября 2019

У меня есть два списка словарей, названных как category и sub_category.

category = [{'cat_id':1,'total':300,'from':250},{'cat_id':2,'total':100,'from':150}]
sub_category = [{'id':1,'cat_id':1,'charge':30},{'id':2,'cat_id':1,'charge':20},{'id':3,'cat_id':2,'charge':30}]

Я хочу изменить значение для charge на 0 в sub_category, если значение total >= fromв category, где cat_id равны.

Ожидаемый результат:

sub_category = [{'id':1,'cat_id':1,'charge':0},{'id':2,'cat_id':1,'charge':0},{'id':3,'cat_id':2,'charge':30}]

Мне удалось получить результат с помощью этого

for sub in sub_category:
    for cat in category:
        if cat['cat_id'] == sub['cat_id']:
            if cat['total'] >= cat['from']:
                sub['charge']=0

Но я хочу знать лучший способ сделать это. Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

1 голос
/ 04 ноября 2019

Попробуйте:

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

category = [{'cat_id':1,'total':300,'from':250},{'cat_id':2,'total':100,'from':150}]
sub_category = [{'id':1,'cat_id':1,'charge':30},{'id':2,'cat_id':1,'charge':20},{'id':3,'cat_id':2,'charge':30}]
print [sub_cat if cat['cat_id'] == sub_cat['id'] and cat['total'] >= cat['from'] and not sub_cat.__setitem__('charge','0') else sub_cat for sub_cat in sub_category for cat in category]

Result:[{'cat_id': 1, 'charge': '0', 'id': 1}, {'cat_id': 1, 'charge': '0', 'id': 1}, {'cat_id': 1, 'charge': 20, 'id': 2}, {'cat_id': 1, 'charge': 20, 'id': 2}, {'cat_id': 2, 'charge': 30, 'id': 3}, {'cat_id': 2, 'charge': 30, 'id': 3}]
1 голос
/ 04 ноября 2019

Вы можете решить свою проблему, используя этот подход:

target_categories = set([elem.get('cat_id') for elem in category if elem.get('total', 0) >= elem.get('from', 0)])
if None in target_categories:
    target_categories.remove(None) # if there's no cat_id in one of the categories we will get None in target_categories. Remove it.
for elem in sub_category:
    if elem.get('cat_id') in target_categories:
        elem.update({'charge': 0})

Сравнение времени с другим подходом:

import numpy as np

size = 5000000
np.random.seed()

cat_ids = np.random.randint(50, size=(size,))
totals = np.random.randint(500, size=(size,))
froms = np.random.randint(500, size=(size,))

category = [{'cat_id': cat_id, 'total': total, 'from': from_} for cat_id, total, from_ in zip(cat_ids, totals, froms)]
sub_category = [{'id': 1, 'cat_id': np.random.randint(50), 'charge': np.random.randint(100)} for i in range(size)]

%%time
target_categories = set([elem.get('cat_id') for elem in category if elem.get('total', 0) >= elem.get('from', 0)])
if None in target_categories:
    target_categories.remove(None) # if there's no cat_id in one of the categories we will get None in target_categories. Remove it.
for elem in sub_category:
    if elem.get('cat_id') in target_categories:
        elem.update({'charge': 0})
# Wall time: 3.47 s

%%time
category = {i.pop('cat_id'): i for i in category}
for i in sub_category:
    if i['cat_id'] in category:
        if category[i['cat_id']]['total'] >= category[i['cat_id']]['from']:
            i['charge'] = 0
# Wall time: 5.73 s
1 голос
/ 04 ноября 2019

Это один из подходов. Измените категорию на dict для легкой зацикливания.

Пример:

category = [{'cat_id':1,'total':300,'from':250},{'cat_id':2,'total':100,'from':150}]
sub_category = [{'id':1,'cat_id':1,'charge':30},{'id':2,'cat_id':1,'charge':20},{'id':3,'cat_id':2,'charge':30}]

category = {i.pop('cat_id'): i for i in category}

for i in sub_category:
    if i['cat_id'] in category:
        if category[i['cat_id']]['total'] >= category[i['cat_id']]['from']:
            i['charge'] = 0
print(sub_category)  

Выход:

[{'cat_id': 1, 'charge': 0, 'id': 1},
 {'cat_id': 1, 'charge': 0, 'id': 2},
 {'cat_id': 2, 'charge': 30, 'id': 3}]
0 голосов
/ 04 ноября 2019

Решение:

# Input
category = [{'cat_id':1,'total':300,'from':250},{'cat_id':2,'total':100,'from':150}]
sub_category = [{'id':1,'cat_id':1,'charge':30},{'id':2,'cat_id':1,'charge':20},{'id':3,'cat_id':2,'charge':30}]

# Main code
for k in sub_category:
    if k["cat_id"] in [i["cat_id"] for i in category if i["total"] >= i["from"]]:
        k["charge"] = 0
print (sub_category)

# Output
[{'id': 1, 'cat_id': 1, 'charge': 0}, {'id': 2, 'cat_id': 1, 'charge': 0}, {'id': 3, 'cat_id': 2, 'charge': 30}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...