Python 比循环更有计算效率的东西

Python something more computational efficient than a loop

我正在尝试使用以下代码从 python 中的字典创建图边列表:

graph= []
for key, value in dic_test.items():
    for x in range (0,len(value)):
        if (x+1) < len(value):
            for y in range (1,len(value)):
                if y != x and y>x:
                    graph.append([value[x],value[y]])

这得到了我想要的,例如,如果我得到这个测试字典:

dic_test= {1: ['A', 'E','F','G'], 2: ['B', 'D','X'], 3: ['C',"Y"],4:[],5:['f','h']}

我得到以下输出:

[['A', 'E'],
 ['A', 'F'],
 ['A', 'G'],
 ['E', 'F'],
 ['E', 'G'],
 ['F', 'G'],
 ['B', 'D'],
 ['B', 'X'],
 ['D', 'X'],
 ['C', 'Y'],
 ['f', 'h']]

问题是当我 运行 一个大字典时它 运行 直到内核崩溃,我有什么想法可以使这段代码更有效率吗?

您可以使用itertools.combinations()
(参见 how to get all combinations of a list's elements):

import itertools
dic_test= {1: ['A', 'E','F','G'], 2: ['B', 'D','X'], 3: ['C',"Y"],4:[],5:['f','h']}

_combinations = []
for _value in dic_test.values():
    _combinations.extend(list(itertools.combinations(_value, 2)))

print(_combinations)

[('A', 'E'),
 ('A', 'F'),
 ('A', 'G'),
 ('E', 'F'),
 ('E', 'G'),
 ('F', 'G'),
 ('B', 'D'),
 ('B', 'X'),
 ('D', 'X'),
 ('C', 'Y'),
 ('f', 'h')]

因为你导入了itertools,使用itertools.chain()可以做下面的一行:

list(itertools.chain(*[list(itertools.combinations(_value, 2)) for _value in dic_test.values()]))

注意

1.性能问题:
- list.extend():每个循环 7.23 µs
- itertools.chain():每个循环 8.15 µs

2。巨大,非常巨大,非常非常非常巨大的词典:
由于您对每个键执行的操作彼此独立,因此您可以并行化您的任务(multiprocessing documentation 如果需要)

Itertools 在这里可能对您有所帮助,因为每条边只是每个子列表中顶点的 2 项组合:

import itertools

output = []
for links in dic_test.values():
    output += map(list, itertools.combinations(links, 2))
for val in dic_test.values():
     a=itertools.combinations(val,2)
     for c in a:
         print(c)

给出输出

('A', 'E')
('A', 'F')
('A', 'G')
('E', 'F')
('E', 'G')
('F', 'G')
('B', 'D')
('B', 'X')
('D', 'X')
('C', 'Y')
('f', 'h')

除了提供 itertools 的建议之外,值得注意的是您还有多组不相交的点击。这意味着您不需要一次完成所有这些计算,当然也不需要同时将所有结果存储在内存中。这也意味着您可以 parallelize.