Попытка условно добавить кортежи из списка кортежей к подспискам кортежей в словаре - PullRequest
0 голосов
/ 20 января 2019

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

У меня есть словарь, в котором каждое значение представляет собой список кортежей (я назову его dict1), на который я делаю перекрестные ссылки на список кортежей (я назову его list1). Идея состоит в том, чтобы добавить любой кортеж, который находится в списке list1, к каждому подсписку в dict1, если он еще не существует в подсписке в форме (tuple, 0).

Вот как это выглядит:

dict1 = {2011: [('Debt collection', 5572),
                ('Mortgage', 4483),
                ('Student loan', 431)],
         2012: [('Consumer Loan', 480),
                ('Student loan', 1632),
                ('Medical loan', 1632),
                ('Prepaid card', 83)]}

list1 = [('Debt collection', 5572),
         ('Mortgage', 4483),
         ('Credit reporting', 3230),
         ('Checking or savings account', 2068),
         ('Student loan', 1632),
         ('Credit card or prepaid card', 1577),
         ('Bank account or service', 1327),
         ('Credit card', 1156),
         ('Consumer Loan', 480)]

Я хочу, чтобы мой код проверял, существует ли первая часть каждого кортежа в списке list1 в каждом списке значений dict1, и, если это не так, добавляет его к каждому списку значений в виде (tuple, 0):

dict1 = {2011: [('Debt collection', 5572),
                ('Mortgage', 4483),
                ('Student loan', 431),
                ('Credit reporting', 0),
                ('Checking or savings account', 0),
                ('Credit card or prepaid card', 0),
                ('Bank account or service', 0),
                ('Credit card', 0),
                ('Consumer Loan', 0)],
         2012: [('Consumer Loan', 480),
                ('Student loan', 1632),
                ('Medical loan', 1632),
                ('Prepaid card', 83),
                ('Debt collection', 0),
                ('Mortgage', 0),
                ('Credit reporting', 0),
                ('Checking or savings account', 0),
                ('Credit card or prepaid card', 0),
                ('Bank account or service', 0),
                ('Credit card', 0)]}

Сначала я попытался извлечь первую часть каждого кортежа из списка list1 как отдельный список:

 available = [tpl[0] for tpl in list1]

Затем я пытаюсь сделать следующее:

 dict1.update(v.extend(tuple((tpl[0],0)) for tpl in v \ 
              for k, v in dict1.items() \
              if tpl[0] not in available))

Я получаю следующую ошибку:

TypeError                                 Traceback (most recent call last)
<ipython-input-79-53b4b903b6f4> in <module>()
----> 1 dict1.update(v.extend(list(tuple((tpl[0],0)) for tpl in v for k, v in dict1.items()                      
if tpl[0] not in available)))

<ipython-input-79-53b4b903b6f4> in <genexpr>(.0)
----> 1 dict1.update(v.extend(list(tuple((tpl[0],0)) for tpl in v for k, v in dict1.items()                      
if tpl[0] not in available)))

TypeError: 'generator' object is not subscriptable

Я искал, но не нашел ничего, что действительно подходило бы к подобному делу. Я предполагаю, что мне нужно использовать .update для dict1, а также .extend в каждом списке значений (v), чтобы иметь дело с каждым списком в отдельности.

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Вы можете временно преобразовать каждое значение в dict, использовать get для обеспечения полного дополнения значений и записать его обратно в виде списка. Это не требует импорта:

for k in dict1:
    d = dict(dict1[k])
    dict1[k] = [(item, d.get(item, 0)) for item, _ in list1]

Если вы хотите иметь словарь в выводе, последняя строка почти не меняется:

dict1[k] = {item: d.get(item, 0)) for item, _ in list1}

Или, если порядок имеет значение, и вы используете Python <3.6: </p>

dict1 = OrderedDict(item, d.get(item, 0)) for item, _ in list1)

Хотя я бы посоветовал вам не делать этого, возможен один вкладыш:

dict1 = {k: [(item, d.get(item, 0)) for item, _ in list1] for k, d in ((k, dict(v)) for k, v in dict1.items())}
0 голосов
/ 20 января 2019

Для вашей проблемы со словарями легче работать, чем со списками кортежей. В этом случае вы можете комбинировать сопоставления с помощью словарного понимания.

from operator import itemgetter

# create dictionary with all keys set to 0
allkeys = dict.fromkeys(map(itemgetter(0), list1), 0)

# for each year, combine dictionary mappings
dict1 = {k: {**allkeys, **dict(v)} for k, v in dict1.items()}

Вы можете, если хотите, преобразовать обратно в списки кортежей:

res = {k: list(v.items()) for k, v in dict1.items()}

Результат для вложенного словаря:

{2011: {'Debt collection': 5572,
  'Mortgage': 4483,
  'Credit reporting': 0,
  'Checking or savings account': 0,
  'Student loan': 431,
  'Credit card or prepaid card': 0,
  'Bank account or service': 0,
  'Credit card': 0,
  'Consumer Loan': 0},
 2012: {'Debt collection': 0,
  'Mortgage': 0,
  'Credit reporting': 0,
  'Checking or savings account': 0,
  'Student loan': 1632,
  'Credit card or prepaid card': 0,
  'Bank account or service': 0,
  'Credit card': 0,
  'Consumer Loan': 480,
  'Medical loan': 1632,
  'Prepaid card': 83}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...