我有一个词典列表,每个词典的格式如下:
{'A': a,'B': b}
我想遍历列表,并且对于每个(a,b)对,找到对(b,a),如果它存在。
例如,如果对于列表A = 13和B = 14的给定条目,则原始对将是(13,14)。我想搜索整个dicts列表以找到该对(14,13)。如果(14,13)多次发生,我也想记录。
我想计算列表中所有原始(a,b)对的次数,当补码(b,a)出现时,如果是,则计算多少次。要做到这一点,我找到了两个for循环和一个计数器。
pairs_found = 0
for i, val in enumerate( list_of_dicts ):
for j, vol in enumerate( list_of_dicts ):
if val['A'] == vol['B']:
if vol['A'] == val['B']:
pairs_found += 1
这会产生大于pairs_found
长度的list_of_dicts
。我意识到这是因为相同的对将被过度计算。我不确定如何克服这种堕落?
编辑清晰度
list_of_dicts = []
list_of_dicts[0] = {'A': 14, 'B', 23}
list_of_dicts[1] = {'A': 235, 'B', 98}
list_of_dicts[2] = {'A': 686, 'B', 999}
list_of_dicts[3] = {'A': 128, 'B', 123}
....
让我们说该列表有大约100000个条目。在该列表的某处,将有一个或多个条目,形式为{'A'23,'B':14}。如果这是真的那么我想要一个计数器将其值增加一。我想为列表中的每个值执行此操作。
答案 0 :(得分:2)
以下是我的建议:
然后代码应如下所示:
# Create a set of unique inverted pairs
inverted_pairs_set = {(d['B'],d['A']) for d in list_of_dicts}
# Create a counter for original pairs
pairs_counter_dict = {(ip[1],ip[0]):0 for ip in inverted_pairs_set]
# Create list of pairs
pairs_list = [(d['A'],d['B']) for d in list_of_dicts]
# Count for each inverted pairs, how many times
for p in pairs_list:
if p in inverted_pairs_set:
pairs_counter_dict[(p[1],p[0])] += 1
答案 1 :(得分:1)
您可以先创建一个列表,其中每个字典的值为元组:
example_dict = [{"A": 1, "B": 2}, {"A": 4, "B": 3}, {"A": 5, "B": 1}, {"A": 2, "B": 1}]
dict_values = [tuple(x.values()) for x in example_dict]
然后创建第二个列表,其中每个元素的出现次数都被反转:
occurrences = [dict_values.count(x[::-1]) for x in dict_values]
最后,创建一个以dict_values
为键,occurrences
为值的词典:
dict(zip(dict_values, occurrences))
输出:
{(1, 2): 1, (2, 1): 1, (4, 3): 0, (5, 1): 0}
对于每个键,您都有反转键的数量。您还可以动态创建字典:
occurrences = {dict_values: dict_values.count(x[::-1]) for x in dict_values}
答案 2 :(得分:1)
我仍然不能100%确定你想做什么,但这是我的猜:
pairs_found = 0
for i, dict1 in enumerate(list_of_dicts):
for j, dict2 in enumerate(list_of_dicts[i+1:]):
if dict1['A'] == dict2['B'] and dict1['B'] == dict2['A']:
pairs_found += 1
请注意第二个for
循环上的切片。这避免了检查之前已经检查过的对(将D1与D2进行比较就足够了;不需要将D2与D1进行比较)
这比O(n ** 2)好,但仍有改进的余地
答案 3 :(得分:1)
您可以创建一个包含所有词典中'A'
和'B'
键值的计数器词典:
complements_cnt = {(dct['A'], dct['B']): 0 for dct in list_of_dicts}
然后您需要的是再次遍历您的词典并增加"补充"的值:
for dct in list_of_dicts:
try:
complements_cnt[(dct['B'], dct['A'])] += 1
except KeyError: # in case there is no complement there is nothing to increase
pass
例如,使用list_of_dicts
:
list_of_dicts = [{'A': 1, 'B': 2}, {'A': 2, 'B': 1}, {'A': 1, 'B': 2}]
这给出了:
{(1, 2): 1, (2, 1): 2}
基本上说{'A': 1, 'B': 2}
有一个补码(第二个)而{'A': 2, 'B': 1}
有两个(第一个和最后一个)。
解决方案是O(n)
,即使对于100000个词典也应该非常快。
注意:这与@debzsud答案非常相似。在我发布答案之前,我还没有看到它。 :(