通过删除循环来优化Python代码

时间:2014-01-16 21:53:02

标签: python loops

我目前正在编写一个程序,它接受多个圆的点,存储为coor_input中的元组(x,y,z),来自csv文件并处理它们,每个圆圈由z坐标标识,我有管理这个,但使用多个循环,我想优化速度和整洁。我尝试过使用

    for zs in coor_input:
        if zs[2] not in z:
            z.append(zs[2])

但这与for循环几乎完全相同。我目前正在使用 下面的代码有效,但我正在寻找一种方法来缩小它,如果可能的话?

coor_input是存储为元组的坐标列表((1,2,3),(4,5,6)...)

    #store each circle value of z coordinate
    for ii in range(0, len(coor_input)):
        if coor_input[ii][2] not in z:
            z.append(coor_input[ii][2])

    #each z identifies different circle
    #go through each circle
    for j in range(0, len(z)):
        #reset coordinates
        coordinates = []

        #add coordinates to the circle of they have the 
        #same z coordinate as the circle
        for f in range(0, len(coor_input)):
            if coor_input[f][2] == z[j]:
                #add coordinates of that circle
                coordinates.append(coor_input[f])

        #Process circle

必须有一种方法来优化这一点,但我不知道任何帮助将不胜感激

3 个答案:

答案 0 :(得分:4)

在字典中收集圆圈,按z坐标键入:

from collections import defaultdict

circles = defaultdict(list):

for x, y, z in coor_input:
    circles[z].append((x, y, z))

这使用collections.defaultdict()object来简化每个z坐标的列表实现;这是一个简单的dict子类,可以像任何普通字典一样使用。

现在你有一个字典,其值是列表,每个z坐标一个列表。这需要一个单循环来收集它们。然后,您可以处理给定z坐标的所有圈子:

for z, coords in circles.iteritems():
    # process circle
    # coords is a list of (x, y, z) coordinates where z is the same

您的代码似乎忽略了第一个找到的圆坐标;如果这是故意的,只需使用coords[1:]跳过为给定z点找到的第一个坐标。

答案 1 :(得分:0)

不要将z列为一个列表,而是设置一个列表。然后你得到O(1)效率:

z = set()
for zs in coor_input:
    z.add(zs[2])

编辑以减少每条评论的愚蠢

答案 2 :(得分:0)

考虑使用列表理解,这可能非常快。例如,假设您想通过某个函数处理每个圆。我会在这里任意定义一个,但它几乎可以是任何东西。

def process_circle(circle):
    return math.sqrt(circle[0]^2 + circle[1]^2 + circle[2]^2)

现在,我们可以在coor_input中快速创建每个圈子上此处理结果的列表,如下所示:

[ process_circle(c) for c in coor_input ]

将所有内容整合到一个测试程序中:

import math

coor_input = ( (1,2,3), (4,5,6), (3,9,3), (2,3,6) )

def process_circle(circle):
    return math.sqrt(circle[0]^2 + circle[1]^2 + circle[2]^2)

print [ process_circle(c) for c in coor_input ]

结果是:

[1.4142135623730951, 3.0, 3.872983346207417, 3.605551275463989]

如果必须按照第三个(z)值的顺序处理它们,则可以使用:

print [ process_circle(c) for c in sorted(coor_input, cmp=lambda a,b: cmp(a[2],b[2])) ]