首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查字典列表值中的值是否唯一

检查字典列表值中的值是否唯一
EN

Stack Overflow用户
提问于 2020-02-03 19:53:39
回答 4查看 74关注 0票数 0

我有两本字典:

代码语言:javascript
复制
mems = {'member2': ['PCP1', 'PCP2'],
  'member6': ['PCP1', 'PCP5'],
  'member7': ['PCP2', 'PCP4', 'PCP5'],
  'member9': ['PCP1', 'PCP5']}


provs = {'PCP1': 2, 'PCP2': 1, 'PCP4': 1, 'PCP5': 1}

如何检查这些列表值中的项是否是唯一的,并且在字典中没有出现在其他地方?如果它是唯一的,那么在一个名为matches = dict()的新字典中添加‘成员’和那个'PCP‘,从'mems'中删除该成员,然后在provs中的计数中添加任何其他剩余的'PCP’。哦,删除mems中唯一的一个

结果应该是

代码语言:javascript
复制
mems = {'member2': ['PCP1', 'PCP2'],
'member6': ['PCP1', 'PCP5'],
'member7': ['PCP2', 'PCP4', 'PCP5'],
'member9': ['PCP1', 'PCP5']}

provs = {'PCP1': 2, 'PCP2': 2, 'PCP5': 2}

matches = ['member7' : 'PCP4'}

我不知道该怎么做。我试着开始为mems中的PCP做一个计数器,然后找到带有1的计数器,然后添加到matches中,但是它给出了错误的成员‘member 9’。

代码语言:javascript
复制
pcpCounts = dict(collections.Counter(itertools.chain.from_iterable(new_members.values())))
print(pcpCounts)
{'PCP1': 3, 'PCP2': 2, 'PCP4': 1, 'PCP5': 2}

for (k,v), (k2,v2) in zip(memsCounter.items(), pcpCounter.items()):
if v2 == 1:
    match[k] = k2

print(matches)
{'member9': 'PCP4'}

为什么当我这么做的时候,正直的人不能保持。更重要的是,有没有更好的方法来做到这一点?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-03 20:42:10

代码语言:javascript
复制
mems = {'member2': ['PCP1', 'PCP2'],
  'member6': ['PCP1', 'PCP5'],
  'member7': ['PCP2', 'PCP4', 'PCP5'],
  'member9': ['PCP1', 'PCP5']}

provs = {'PCP1': 2, 'PCP2': 1, 'PCP4': 1, 'PCP5': 1}

首先,您可以反转mems

代码语言:javascript
复制
d1 = {}
for mem, pcps in mems.items():
    for pcp in pcps:
        d1.setdefault(pcp, []).append(mem)

# {'PCP1': ['member2', 'member6', 'member9'], 'PCP2': ['member2', 'member7'], 'PCP5': ['member6', 'member7', 'member9'], 'PCP4': ['member7']}

现在很容易计算matches:过滤len(mems)上的dict并再次反转它:

代码语言:javascript
复制
matches = {mems[0]: pcp for pcp, mems in d1.items() if len(mems) == 1}
# {'member7': 'PCP4'}

您可以创建不包含匹配new_memspcp的dict。

代码语言:javascript
复制
new_mems = {mem: [pcp for pcp in pcps if pcp not in matches.values()] for mem, pcps in mems.items()}
# {'member2': ['PCP1', 'PCP2'], 'member6': ['PCP1', 'PCP5'], 'member7': ['PCP2', 'PCP5'], 'member9': ['PCP1', 'PCP5']}

然后使用计数器更新provs

代码语言:javascript
复制
import collections
new_provs = collections.Counter(provs)
for mem, pcp in matches.items():
    new_provs.update(mems[mem]) # add 1 to each count
    new_provs[pcp] -= 2 # was 0 + 1 (line above) -> is 0

# Counter({'PCP1': 2, 'PCP2': 2, 'PCP5': 2, 'PCP4': 0})
票数 1
EN

Stack Overflow用户

发布于 2020-02-03 20:13:40

要启动它,如果您创建一个集合,先查看它是否存在,然后找到它所属的成员,它可能会变得更容易。

代码语言:javascript
复制
mems = {'member2': ['PCP1', 'PCP2'],
  'member6': ['PCP1', 'PCP5'],
  'member7': ['PCP2', 'PCP4', 'PCP5'],
  'member9': ['PCP1', 'PCP5']}

provs = {'PCP1': 2, 'PCP2': 1, 'PCP4': 1, 'PCP5': 1}

members = {}
x = set()
for k,v in mems.items():
    for i in v:
        x.add(i)
        try:
            members[i].append(k)
        except KeyError:
            members[i] = [k,]

print(x)
print(members)

for k in provs:
    if k in x:
        print('KEY: {0} in {1}'.format(k,members[k]))
        print('KEY: {0} in {1}'.format(k,len(members[k]))) # count the references. 
票数 2
EN

Stack Overflow用户

发布于 2020-02-03 20:20:33

您仍然可以在这里使用计数器,只需将其转换为仅由单个出现的prov过滤的集合,然后使用set.intersection作为您的检查。

代码语言:javascript
复制
from collections import Counter

mems = {'member2': ['PCP1', 'PCP2'], 'member6': ['PCP1', 'PCP5'], 'member7': ['PCP2', 'PCP4', 'PCP5'], 'member9': ['PCP1', 'PCP5']}
provs = {'PCP1': 2, 'PCP2': 1, 'PCP4': 1, 'PCP5': 1}

#I'm using sum here instead of itertools.chain. It serves the same purpose
prov_counts = {p for p, c in Counter(sum(mems.values(), [])).items() if c == 1} 
prov_filter = map(prov_counts.intersection, mems.values())

matches = {m: list(p) for m, p in zip(mems, prov_filter) if p}

print(matches)

代码语言:javascript
复制
{'member7': ['PCP4']}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60046251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档