Python比循环更有计算效率

时间:2018-03-08 15:30:53

标签: python performance loops dictionary edges

我试图用python中的字典制作图表边缘列表,代码如下:

// MARK: - ARSCNViewDelegate (Image detection results)
/// - Tag: ARImageAnchor-Visualizing
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let imageAnchor = anchor as? ARImageAnchor else { return }
    let referenceImage = imageAnchor.referenceImage
    updateQueue.async {

        // Create a plane to visualize the initial position of the detected image.
        let plane = SCNPlane(width: referenceImage.physicalSize.width,
                         height: referenceImage.physicalSize.height)
        plane.materials.first?.diffuse.contents = UIColor.blue.withAlphaComponent(0.20)
        self.planeNode = SCNNode(geometry: plane)

        self.planeNode?.opacity = 1

        /*
         `SCNPlane` is vertically oriented in its local coordinate space, but
         `ARImageAnchor` assumes the image is horizontal in its local space, so
         rotate the plane to match.
         */
        self.planeNode?.eulerAngles.x = -.pi / 2

        /*
         Image anchors are not tracked after initial detection, so create an
         animation that limits the duration for which the plane visualization appears.
         */

        // Add the plane visualization to the scene.
        if let planeNode = self.planeNode {
            node.addChildNode(planeNode)
        }

        if let imageName = referenceImage.name {
            plane.materials = [SCNMaterial()]
            plane.materials[0].diffuse.contents = UIImage(named: imageName)
        }
    }

    DispatchQueue.main.async {
        let imageName = referenceImage.name ?? ""
        self.statusViewController.cancelAllScheduledMessages()
        self.statusViewController.showMessage("Detected image “\(imageName)”")
    }
}

这可以得到我想要的,例如,如果我得到这个测试词典:

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']}

问题是,当我运行一个大字典时,它运行直到内核崩溃,我可以使这些代码更有效的任何想法?

4 个答案:

答案 0 :(得分:0)

您可以使用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如果需要)

答案 1 :(得分:0)

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

import itertools

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

答案 2 :(得分:0)

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')

答案 3 :(得分:0)

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