将偏移对添加到平面列表中的对

时间:2017-10-06 23:15:09

标签: python python-2.7

我有一个平面的坐标列表:

points=[x1,y1,x2,y2,...,xN,yN]

我需要为所有这些添加一个偏移对(dx,dy):

points=[x1+dx,y1+dy,x2+dx,y2+dy,...,xN+dx,yN+dy]

由于经常这样做,效率很重要。有没有比

更好的方法
for i in range(0,len(points),2):
    points[i]+=dx
    points[i+1]+=dy

3 个答案:

答案 0 :(得分:1)

您可以使用itertools.cycle为代码添加更多优雅,并依次添加循环对象中的元素:

from itertools import cycle

cyc = cycle([dx, dy])
for i in range(len(points)):
    points[i] += next(cyc)

如果您需要创建新列表,可以轻松将其扩展为列表解析:

from itertools import cycle

cyc = cycle([dx, dy])
lst = [x + next(cyc) for x in points]

OTOH,如果你想超高效,你可以使用numpy执行添加(需要安装numpy):

import numpy as np

points = np.array(...)
points[::2] += dx
points[1::2] += dy

答案 1 :(得分:1)

是否允许numpy。我会用numpy来做这件事:

points = points.reshape(-1, 2)
points += np.array([dx, dy])

答案 2 :(得分:1)

因此,使用上面的建议,快速进行性能测试。由于我需要输入列表的副本,如果代码没有执行,我会进行显式复制:

import timeit
from itertools import cycle


def plainLoop(pointsIn,dx,dy):
    pointsOut=pointsIn[:]
    for i in range(0,len(pointsOut),2):
        pointsOut[i]+=dx
        pointsOut[i+1]+=dy
    return pointsOut

def cycleAndLoop(pointsIn,dx,dy):
    offsets = cycle([dx, dy])
    pointsOut=pointsIn[:]
    for i in range(len(pointsOut)):
        pointsOut[i] += next(offsets)
    return pointsOut

def cycleAndComprehension(pointsIn,dx,dy):
    offsets = cycle([dx, dy])
    pointsOut=[c+next(offsets) for c in pointsIn]
    return pointsOut

points=[float(i) for i in range(50*6)]

number=1000
repeat=1000

print 'plainLoop:',             min(timeit.repeat('plainLoop(points,.1,.2)',setup='from __main__ import plainLoop,points',number=number,repeat=repeat))
print 'cycleAndLoop:',          min(timeit.repeat('cycleAndLoop(points,.1,.2)',setup='from __main__ import cycleAndLoop,points',number=number,repeat=repeat))
print 'cycleAndComprehension:', min(timeit.repeat('cycleAndComprehension(points,.1,.2)',setup='from __main__ import cycleAndComprehension,points',number=number,repeat=repeat))

输入数组的大小(50 * 6)代表描述许多字体中字符的三元组数。结果:

             cycleAndLoop:: min: 3.718e-01, avg: 3.926e-01, max: 4.301e-01
    cycleAndComprehension:: min: 2.999e-01, avg: 3.144e-01, max: 3.388e-01
                plainLoop:: min: 1.908e-01, avg: 2.034e-01, max: 2.364e-01

所以是的,普通循环是该批次中最快的,但是理解中循环()解决方案的50%性能损失可以通过代码的简洁性来补偿。