#python #list #dictionary
#python #Список #словарь
Вопрос:
у меня есть следующий список словарей:
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumRefund': 298}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumCashBack': 10586}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'MasterCard', 'sumTotal': 14}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa', 'sumTotal': 10}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumTotal': 40}
как бы мне объединить их, чтобы ключ cardscheme был уникальным — это потребует объединения sumRefund и sumCashback в одну строку (пример shwon ниже), но я не могу понять это.
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'MasterCard', 'sumTotal': 14}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa', 'sumTotal': 10}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumTotal': 40, 'sumRefund': 298, 'sumCashBack': 10586}
Комментарии:
1. Правильный ли ваш желаемый результат? Как и в случае
MasterCard
с , здесь нетsumRefund
andsumCashBack
, но оно есть в желаемом выводе…2. о, извините, я полностью все испортил, я отредактирую это, чтобы исправить, спасибо, что дали мне знать
3. время публикации defaultdict soln: 8.65000000000010039e-05, тогда как два цикла, опубликованные (мной :)) ниже, чем 2.3500000000176158e-05. Это важно, однако еще предстоит выяснить, содержит ли список тысячи записей, поле сужается.
Ответ №1:
Вы можете использовать метод обновления словаря вместе с defaultdict . Предполагая, что L
это исходный список:
from collections import defaultdict
cardschemes_rules = defaultdict(dict)
for dic in L:
cardschemes_rules[dic['cardscheme'] dic['posid']].update(dic)
cardschemes_rules.values()
Как вы просили в комментарии, каждый вывод соответствует объединению ключей для данной (cardscheme, posid)
пары.
Запуск этого кода со следующим L
:
L = [
{'posid': 'A', 'cardscheme': 'Visa Debit', 'sumRefund': 2.98},
{'posid': 'A', 'cardscheme': 'Visa Debit', 'sumCashBack': 105.86},
{'posid': 'A', 'cardscheme': 'MasterCard', 'sumTotal': .14},
{'posid': 'A', 'cardscheme': 'Visa Debit', 'sumTotal': .40},
{'posid': 'B', 'cardscheme': 'Visa Debit', 'sumRefund': 298},
{'posid': 'B', 'cardscheme': 'Visa Debit', 'sumCashBack': 10586},
{'posid': 'B', 'cardscheme': 'Visa', 'sumTotal': 10},
]
Приведет к cardschemes_rules.values()
:
{'posid': 'A', 'cardscheme': 'Visa Debit', 'sumRefund': 2.98, 'sumCashBack': 105.86, 'sumTotal': 0.4}
{'posid': 'A', 'cardscheme': 'MasterCard', 'sumTotal': 0.14}
{'posid': 'B', 'cardscheme': 'Visa Debit', 'sumRefund': 298, 'sumCashBack': 10586}
{'posid': 'B', 'cardscheme': 'Visa', 'sumTotal': 10}
Если у вас есть коллизии имен при вводе, последняя запись в списке ввода останется (значение заменяется новым при каждом update
применении).
Комментарии:
1. Это отлично работает, когда есть один
posid
, как я мог бы разрешить присутствие несколькихposid
ключей?2. Если их несколько
posid
, вам нужно будет включитьposid
вcardschemes_rules
ключ, напримерcardschemes_rules[dic['cardscheme'] dic['posid']
, таким образом, вы будете обновлять словари для каждойcardscheme
posid
пары. Подойдет любой ключ, включающий оба поля. Он просто должен быть уникальным для каждой парыcardscheme
,posid
.
Ответ №2:
Я бы использовал pandas:
import pandas as pd
data = [
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumRefund': 298},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumCashBack': 10586},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'MasterCard', 'sumTotal': 14},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa', 'sumTotal': 10},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumTotal': 40}
]
df = pd.DataFrame()
for line in data:
df = df.append(line, ignore_index=True)
df = df.fillna(0)
df = df.groupby('cardscheme').sum()
df.to_csv('test.csv')
Надеюсь, я помог 🙂
Комментарии:
1. Это очень близко, но когда он запускается, я теряю значение posid
2. вы можете использовать список аргументов для группировки, например. df.groupby([‘cardscheme’, ‘posid’]).sum()
Ответ №3:
Пробовал с минимальными итерациями, но это лучшее, с чем я столкнулся.
Код:
lst = [{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumRefund': 298},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumCashBack': 10586},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'MasterCard', 'sumTotal': 14},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa', 'sumTotal': 10},
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumTotal': 40}]
uniq_lst = []
for dct in lst:
updated = False
for dct_res in uniq_lst:
if dct_res['posid'] == dct['posid'] and dct_res['cardscheme'] == dct['cardscheme']:
dct_res[list(dct.keys())[2]] = list(dct.values())[2]
updated = True
break
else:
uniq_lst.append(dct)
updated = True
if not updated:
uniq_lst.append(dct)
for ele in uniq_lst:
print(ele)
Вывод:
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa Debit', 'sumRefund': 298, 'sumCashBack': 10586, 'sumTotal': 40}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'MasterCard', 'sumTotal': 14}
{'posid': 'AZDEMOBirminghamB134', 'cardscheme': 'Visa', 'sumTotal': 10}