[英]How can I dynamically combine sets in python
I have a list of dictionaries and need to iterate through them and check for the keys that exist already. 我有一个字典列表,需要遍历它们并检查已经存在的键。 I have implemented a python code to manually calculate a score as below. 我已经实现了一个python代码来手动计算得分,如下所示。 In my code, I'm manually combining keys from previous dictionaries in each iteration. 在我的代码中,我在每次迭代中手动组合先前字典中的键。 Iteration will start from dict11. 迭代将从dict11开始。
How can I change this code to automatically iterate through a dynamic number of dictionaries and in each iteration how can I combine the keys dynamically? 如何更改此代码以自动迭代动态数量的词典,并且在每次迭代中如何动态组合键?
dict10 = {'A': 1, 'C': 2}
dict11 = {'B': 3, 'C': 4}
dict12 = {'A': 5, 'E': 6, 'F': 7}
dict13 = {'G': 8, 'E': 9}
exist_score = 0
for key in dict11.keys() & dict10.keys():
exist_score += dict11[key]
for key in dict12.keys() & set(dict11.keys()).union(set(dict10.keys())):
exist_score += dict12[key]
for key in dict13.keys() & set(dict12.keys()).union(set(dict11.keys()).union(set(dict10.keys()))):
exist_score += dict13[key]
print(exist_score)
First you need to turn this into something that can be put into a loop. 首先,您需要将其变成可以放入循环的内容。 The same thing has to happen with dict11
, dict12
and dict13
: dict11
, dict12
和dict13
必须发生相同的事情:
# same definition for dict10, dict11, dict12, dict13
exist_score = 0
seen_keys = set(dict10.keys())
for key in dict11.keys():
if key in seen_keys:
exist_score += dict11[key]
seen_keys.update(dict11.keys())
for key in dict12.keys():
if key in seen_keys:
exist_score += dict12[key]
seen_keys.update(dict12.keys())
for key in dict13.keys():
if key in seen_keys:
exist_score += dict13[key]
seen_keys.update(dict13.keys())
This should do the same thing as your script. 这应该与脚本执行相同的操作。 Now you can put that into a loop … 现在,您可以将其放入循环...
# same definition for dict10, dict11, dict12, dict13
exist_score = 0
seen_keys = set(dict10.keys())
other_dicts = [dict11, dict12, dict13]
for d in other_dicts:
for key in d.keys():
if key in seen_keys:
exist_score += d[key]
seen_keys.update(d.keys())
It makes the most sense to keep dicts in a list themselves. 将字典本身保留在列表中是最有意义的。 Putting this logic into a function is also a no-brainer. 将此逻辑放入函数中也很容易。
dicts = [
{'A': 1, 'C': 2},
{'B': 3, 'C': 4},
{'A': 5, 'E': 6, 'F': 7},
{'G': 8, 'E': 9}
]
def score_dicts(dicts):
score = 0
all_keys = set()
for d in dicts:
keys = d.keys()
for key in keys & all_keys:
score += d[key]
all_keys.update(keys)
return score
exist_score = score_dicts(dicts)
If you need to update the score periodically (one dict at a time), you can maintain the state in either a class or a closure. 如果您需要定期更新分数(一次更新一个字典),则可以在类或闭包中维护状态。
Class: 类:
class DictScorer():
def __init__(self):
self.exist_score = 0
self.all_keys = set()
def score(self, d):
keys = d.keys()
for key in keys & self.all_keys:
self.exist_score += d[key]
self.all_keys.update(keys)
return self.exist_score
dict10 = {'A': 1, 'C': 2}
dict11 = {'B': 3, 'C': 4}
dict12 = {'A': 5, 'E': 6, 'F': 7}
dict13 = {'G': 8, 'E': 9}
scorer = DictScorer()
exist_score = scorer.score(dict10)
print(exist_score)
exist_score = scorer.score(dict11)
print(exist_score)
exist_score = scorer.score(dict12)
print(exist_score)
exist_score = scorer.score(dict13)
print(exist_score)
Closure: 关闭:
# returns a scorer which can
# be used incrementally
def create_dict_scorer():
score = 0
all_keys = set()
def dict_scorer(d):
nonlocal score
keys = d.keys()
for key in keys & all_keys:
score += d[key]
all_keys.update(keys)
return score
return dict_scorer
dict10 = {'A': 1, 'C': 2}
dict11 = {'B': 3, 'C': 4}
dict12 = {'A': 5, 'E': 6, 'F': 7}
dict13 = {'G': 8, 'E': 9}
scorer = create_dict_scorer()
exist_score = scorer(dict10)
print(exist_score)
exist_score = scorer(dict11)
print(exist_score)
exist_score = scorer(dict12)
print(exist_score)
exist_score = scorer(dict13)
print(exist_score)
Short magic with slicing and set
operations: 切片和set
操作的简短魔术 :
dicts = [dict10, dict11, dict12, dict13]
exist_score = 0
for i, d in enumerate(dicts[:0:-1]):
offset = -(i - 2)
exist_score += sum(d[k] for k in d.keys() & set().union(*dicts[offset::-1]))
print(exist_score)
dicts[:0:-1]
- slice of dictionaries in reversed order excluding the 1st one dicts[:0:-1]
-字典顺序相反的片,不包括第一个 -(i - 2)
- negative offset to get consecutive "backward" slices for further set
unions -(i - 2)
-负偏移量以获得连续的“向后”切片以进一步set
并set
The output (the same as in your initial approach): 输出(与您的初始方法相同):
18
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.