【解决方案1】:
您可以通过保留对找到的匹配项的引用在线性时间内解决此问题(即不使用双循环)。
我在这里假设每个 C 最多有 2 个匹配项:
dicts = [
{'A':1, 'B':2, 'C':10, 'D':100, 'E':None},
{'A':2, 'B':3, 'C':10, 'D':200, 'E':None},
{'A':3, 'B':4, 'C':20, 'D':300, 'E':None},
{'A':4, 'B':5, 'C':20, 'D':400, 'E':None},
{'A':5, 'B':6, 'C':30, 'D':500, 'E':None},
{'A':6, 'B':7, 'C':30, 'D':600, 'E':None}]
refs = {}
for i, d in enumerate(dicts):
if d['C'] in refs: # we already found the first match
j = refs[d['C']]
# swap the values
dicts[j]['E'], dicts[i]['E'] = dicts[i]['A'], dicts[j]['A']
else: # this is the first match
refs[d['C']] = i # keep a reference of the index
# copy A to E in case of a single match
d['E'] = d['A']
dicts
输出:
[{'A': 1, 'B': 2, 'C': 10, 'D': 100, 'E': 2},
{'A': 2, 'B': 3, 'C': 10, 'D': 200, 'E': 1},
{'A': 3, 'B': 4, 'C': 20, 'D': 300, 'E': 4},
{'A': 4, 'B': 5, 'C': 20, 'D': 400, 'E': 3},
{'A': 5, 'B': 6, 'C': 30, 'D': 500, 'E': 6},
{'A': 6, 'B': 7, 'C': 30, 'D': 600, 'E': 5}]
【问题讨论】:
【解决方案2】:
如果“C”总是有 2 个可能的重复项,您只需确保 x 和 y 不同,然后分配“E”:
dicts = [
{'A':1, 'B':2, 'C':10, 'D':100, 'E':None},
{'A':2, 'B':3, 'C':10, 'D':200, 'E':None},
{'A':3, 'B':4, 'C':20, 'D':300, 'E':None},
{'A':4, 'B':5, 'C':20, 'D':400, 'E':None},
{'A':5, 'B':6, 'C':30, 'D':500, 'E':None},
{'A':6, 'B':7, 'C':30, 'D':600, 'E':None}]
for x in dicts:
for y in dicts:
if y['C'] == x['C'] and y is not x:
x['E'] = y['A']
y['E'] = x['A']
print(dicts)
输出:
[{'A': 1, 'B': 2, 'C': 10, 'D': 100, 'E': 2},
{'A': 2, 'B': 3, 'C': 10, 'D': 200, 'E': 1},
{'A': 3, 'B': 4, 'C': 20, 'D': 300, 'E': 4},
{'A': 4, 'B': 5, 'C': 20, 'D': 400, 'E': 3},
{'A': 5, 'B': 6, 'C': 30, 'D': 500, 'E': 6},
{'A': 6, 'B': 7, 'C': 30, 'D': 600, 'E': 5}]
【问题讨论】:
【解决方案3】:
使用 循环您的听写:
import itertools
dicts = [
{'A':1, 'B':2, 'C':10, 'D':100, 'E':None},
{'A':2, 'B':3, 'C':10, 'D':200, 'E':None},
{'A':3, 'B':4, 'C':20, 'D':300, 'E':None},
{'A':4, 'B':5, 'C':20, 'D':400, 'E':None},
{'A':5, 'B':6, 'C':30, 'D':500, 'E':None},
{'A':6, 'B':7, 'C':30, 'D':600, 'E':None}]
for x, y in itertools.combinations(dicts, 2):
if x['E'] is None: # skip if already set
if x['C'] == y['C']:
x['E'] = y['A']
y['E'] = x['A']
这是有效的,因为在示例 dicts 中只有一对匹配。如果没有,您应该指定如何处理这种情况。
【问题讨论】:
【解决方案4】:
当心 BigO:您的 2 个嵌套 for 循环等于 O(n^2)。
您可以使用哈希表来减少它。
dicts = [
{"A": 1, "B": 2, "C": 10, "D": 100, "E": None},
{"A": 2, "B": 3, "C": 10, "D": 200, "E": None},
{"A": 3, "B": 4, "C": 20, "D": 300, "E": None},
{"A": 4, "B": 5, "C": 20, "D": 400, "E": None},
{"A": 5, "B": 6, "C": 30, "D": 500, "E": None},
{"A": 6, "B": 7, "C": 30, "D": 600, "E": None},
]
c = {}
for i in range(len(dicts)):
if not c.get(dicts[i]["C"]):
c.update({dicts[i]["C"]: {"upper_row": i}})
else:
c[dicts[i]["C"]].update({"lower_row": i})
print(dicts)
print(c)
for value, duplicates in c.items():
lower = duplicates.get("lower_row")
if duplicates.get("lower_row"):
upper = duplicates.get("upper_row")
dicts[upper]["E"] = dicts[lower]["A"]
dicts[lower]["E"] = dicts[upper]["A"]
print(dicts)
输出:
"""
Original state of dicts :
[
{'A': 1, 'B': 2, 'C': 10, 'D': 100, 'E': None},
{'A': 2, 'B': 3, 'C': 10, 'D': 200, 'E': None},
{'A': 3, 'B': 4, 'C': 20, 'D': 300, 'E': None},
{'A': 4, 'B': 5, 'C': 20, 'D': 400, 'E': None},
{'A': 5, 'B': 6, 'C': 30, 'D': 500, 'E': None},
{'A': 6, 'B': 7, 'C': 30, 'D': 600, 'E': None}]
c hashtable :
{10: {'upper_row': 0, 'lower_row': 1}, 20: {'upper_row': 2, 'lower_row': 3}, 30: {'upper_row': 4, 'lower_row': 5}}
Final state of dicts:
[
{'A': 1, 'B': 2, 'C': 10, 'D': 100, 'E': 2},
{'A': 2, 'B': 3, 'C': 10, 'D': 200, 'E': 1},
{'A': 3, 'B': 4, 'C': 20, 'D': 300, 'E': 4},
{'A': 4, 'B': 5, 'C': 20, 'D': 400, 'E': 3},
{'A': 5, 'B': 6, 'C': 30, 'D': 500, 'E': 6},
{'A': 6, 'B': 7, 'C': 30, 'D': 600, 'E': 5}]
"""
【问题讨论】:
【解决方案5】:
bananananananananaanananananananananananananananananananananana
【问题讨论】:
© 版权声明
本站下载的源码均来自公开网络收集转发二次开发而来,
若侵犯了您的合法权益,请来信通知我们1413333033@qq.com,
我们会及时删除,给您带来的不便,我们深表歉意。
下载用户仅供学习交流,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担,访问及下载者下载默认同意本站声明的免责申明,请合理使用切勿商用。
THE END
暂无评论内容