Python 试图有条件地将元组列表中的元组附加到字典中的元组子列表

Python 试图有条件地将元组列表中的元组附加到字典中的元组子列表,python,list,dictionary,tuples,Python,List,Dictionary,Tuples,我不知道如何实现我想要的,所以我在这里发布 我有一个字典,其中每个值都是一个元组列表(我称之为dict1),我将它与一个元组列表(我称之为list1)进行交叉引用。其思想是将列表1中的任何元组附加到dict1中的每个子列表中,前提是它在子列表中尚未以(元组,0)的形式存在 下面是它的样子: dict1 = {2011: [('Debt collection', 5572), ('Mortgage', 4483), ('Student

我不知道如何实现我想要的,所以我在这里发布

我有一个字典,其中每个值都是一个元组列表(我称之为
dict1
),我将它与一个元组列表(我称之为
list1
)进行交叉引用。其思想是将列表1中的任何元组附加到
dict1
中的每个子列表中,前提是它在子列表中尚未以(元组,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)的形式将其附加到每个值列表中:

我首先尝试将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
TypeError回溯(最近一次调用)
在()
---->1 dict1.更新(v.extend(list)(tuple((tpl[0],0)),用于v中的tpl,用于k,v中的dict1.items()
如果第三方物流[0]不可用)
英寸(.0)
---->1 dict1.更新(v.extend(list)(tuple((tpl[0],0)),用于v中的tpl,用于k,v中的dict1.items()
如果第三方物流[0]不可用)
TypeError:“生成器”对象不可下标

我在找,但没有发现任何类似的案例。我假设我必须使用.update for dict1和.extend for每个值列表(v),以便单独处理每个列表。

对于您的问题,字典比元组列表更容易处理。在这种情况下,您可以通过字典合并映射

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}}

您可以将每个值临时转换为
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:

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())}

请注意,生成器表达式返回的是生成器,而不是列表,并且不能订阅生成器;正如错误所指出的那样。您可以使用列表理解而不是生成器表达式,或者使用
list
强制生成器进入列表。我不太擅长生成器表达式,因此我正在尝试更好地理解我的代码…这里的生成器表达式是以v.extend开头的吗?是的。看起来像列表但使用
()
而不是方括号的部分。我看不出你在哪里订阅生成器,但这是我看到的唯一一个生成器实例。嗯……我试着在v.extend之前和“available”之后放上方括号),但我仍然收到相同的错误消息(“generator”对象不可订阅)看起来你真的想要的是一个
集合.OrderedDict
,而不是一个元组列表。
dict1 = {k: [(item, d.get(item, 0)) for item, _ in list1] for k, d in ((k, dict(v)) for k, v in dict1.items())}