【问题标题】:iterating over list-valued dictionary迭代列表值字典
【发布时间】:2021-04-20 22:58:28
【问题描述】:

假设我有一本字典,其中元组作为键,元组列表作为值,例如:

d={(0,1):[(1,1)],
   (0,2):[(1,1),(1,2)],
   (0,3):[(1,1),(1,2),(1,3)]}

我想删除所有条目,使其值包含在另一个键的值中,例如:

从 d 我想删除带有键 (0,1) 的条目,因为 (1,1) 包含在 [(1,1),(1,2)] 中 并删除键为 (0,2) 的条目,因为 [(1,1),(1,2)] 包含在 [(1,1),(1,2),(1,3)] 中。 列表中元组的顺序很重要。

我可以使用一堆 for 循环来解决这个问题,如下所示:

for key, val in d.items():
    for k,v in d.items():
        for i in range(0, len(val)):
            if val[i] in v and len(v) - len(val) == 1:
                del_me = True
            else:
                del_me = False
                break
        if del_me:
             to_del.append(key)
for key in set(to_del):
    del d[key]

编辑:(进一步解释) 键在这里并不重要,但稍后会很重要。 换句话说: 让 a,b,c,d 表示唯一的元组 让 k1,k2,..., 表示键

让我们有条目:

k1:[a],
k2:[d],
k3:[a,b],
k4:[b,a],
k5:[a,b,c],

我想最终得到: k2,k4,k5

删除的条目将是: k1 因为 a 在 k3 k3 因为 a,b 在 k5 中

看到这里眼睛疼,抱歉。

什么是pythonic方式来做到这一点?

【问题讨论】:

  • For-loops 是pythonic。我仍然不完全清楚您要做什么。
  • 键将有序的元组列表作为值。可以通过将更多元组附加到已经是另一个键的值的列表来创建不同键的值。然后我想用更短的列表删除之前的键。
  • 换句话说:我添加了另一个条目。该值是通过将一些新对附加到现有条目的值来构造的。我想删除那个已经存在的条目。我只想保留不包含在另一个条目序列中的最长序列的条目。现在清楚了吗?
  • 字典的顺序会一直保持不变吗?我的意思是最后你会得到只有一个键值对的字典吗? @4rk
  • 会有不止一个键值对,其值的顺序是唯一的;我的意思是最后我希望每个唯一的元组序列都有一个键值对

标签: python dictionary


【解决方案1】:

假设您有一个如下所示的dictionary

d={(0,1):[(1,1)],(0,2):[(1,1),(1,2)],(0,3):[(1,1),(1,2),(1,3)],(0,4):[(1,1),(1,2),(1,4)]}

现在您想将values 与所有keys 相互比较。我建议您将这本字典中的所有值放在list 中。

mylist=[]
for key in d.keys():
    mylist.append(d[key])
    
print(mylist)

mylist 将如下所示,包含字典的所有值。

[[(1, 1)], [(1, 1), (1, 2)], [(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]

现在您想将所有这些值相互比较,并删除其中任何值中的subsets 值。就像在这个例子中一样,[(1,1)][(1,1),(1,2)] 的子集,所以[(1,1)] 将被删除。同样,[(1,1),(1,2)][(1,1),(1,2),(1,3)] 的子集,因此它也将被删除。我们可以这样做:

out = [] 

for k, elm in enumerate(mylist):  
    for _,elm2 in enumerate(mylist[:k] + mylist[k + 1:]):  
        if frozenset(elm).issubset(elm2):  
            break  
    else:  
        out.append(elm)    

print(out)

out 列表将为我们提供列表 mylist 的唯一元素。

[[(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]

在上面的代码段中,我们循环遍历列表并获取当前索引。然后我们在同一个列表上再次循环,但我们删除了第一个循环的当前索引处的元素。然后我们将第一个循环的索引的第一个元素转换为frozenset,并使用issubset方法来检查第一个元素是否是第二个元素的子集。

现在我们只需将我们的字典d 值与out 列表进行比较。如果d 值不在out 列表中,我们从字典d 中删除key。这是按如下方式完成的:

for key in list(d):
    if d[key] not in out:
        del d[key]
        
print(d)

output 字典 d 将是:

{(0, 3): [(1, 1), (1, 2), (1, 3)], (0, 4): [(1, 1), (1, 2), (1, 4)]}

【讨论】:

  • 如果两个值相同会怎样?
  • 它们也将被删除,因为它们不是唯一值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 2013-07-01
相关资源
最近更新 更多