Python:查找列表字段之间的距离

Python:查找列表字段之间的距离,python,list,enumerate,Python,List,Enumerate,嗨,我需要计算列表中每个数字对之间的距离,包括最后一个和第一个之间的距离(它是一个圆) 天真的我可以做这样的事情: l = [10,-12,350] ret = [] for i in range(len(l)-1): ret.append(abs(l[i] - l[i+1])) ret.append(l[-1] - l[0]) print ret out: [22, 362, 340] 我尝试了“枚举”,这是一种更好的方法: print [abs(v - (l+[l[0]])[i+

嗨,我需要计算列表中每个数字对之间的距离,包括最后一个和第一个之间的距离(它是一个圆)

天真的我可以做这样的事情:

l = [10,-12,350]
ret = []
for i in range(len(l)-1):
    ret.append(abs(l[i] - l[i+1]))
ret.append(l[-1] - l[0])
print ret

out: [22, 362, 340]
我尝试了“枚举”,这是一种更好的方法:

print [abs(v - (l+[l[0]])[i+1]) for i, v in enumerate(l)]
out: [22, 362, 340]

还有比这更优雅和“蟒蛇式”的方法吗?

我认为这是一个小小的改进。不过,很可能还有比这更干净的方法:

print [abs(v - l[(i+1)%len(l)]) for i, v in enumerate(l)]

如果你乐意使用numpy

list(numpy.abs(numpy.ediff1d(l, to_end=l[0]-l[-1])))
这与较长的
l
配合得很好。不转换到列表或从列表转换将大大加快速度(通常可以使用numpy数组代替列表)

或者,您可以使用以下方式自行构建:

一些时间安排:

In [37]: l = list(numpy.random.randn(1000))

In [38]: timeit [abs(v - l[(i+1)%len(l)]) for i, v in enumerate(l)]
1000 loops, best of 3: 936 us per loop

In [39]: timeit list(numpy.abs(numpy.ediff1d(l, to_end=l[0]-l[-1])))
1000 loops, best of 3: 367 us per loop

In [40]: _l = numpy.array(l)

In [41]: timeit numpy.abs(numpy.ediff1d(_l, to_end=l[0]-l[-1]))
10000 loops, best of 3: 48.9 us per loop

In [42]: timeit _l = numpy.array(l); list(numpy.abs(_l - numpy.roll(_l, -1)))
1000 loops, best of 3: 350 us per loop

In [43]: timeit numpy.abs(_l - numpy.roll(_l, -1))
10000 loops, best of 3: 32.2 us per loop
如果您喜欢原始速度,则速度更快,但不太整洁,您可以直接使用切片阵列:

In [78]: timeit a = numpy.empty(_l.shape, _l.dtype); a[:-1] = _l[:-1] - _l[1:]; a[-1] = _l[-1] - _l[0]; a = numpy.abs(a)
10000 loops, best of 3: 20.5 us per loop

这不是一个很大的改进:

>>> [abs(a - b) for a, b in zip(l, l[1:] + l[:-1])]
[22, 362, 340]
另一种方法:

print map(lambda x,y: abs(x-y), l[1:] + l[:1], l)

在这种情况下,它可能不如其他答案好,但如果用作更大的代码库的一部分,则定义一个迭代器(返回列表中的项目对)可能会很有用,例如:

def pairs(l):
    if len(l) < 2:
        return

    for i in range(len(l)-1):
        yield l[i], l[i+1]

    yield l[-1], l[0]

print [abs(a - b) for a,b in pairs([10,-12,350])]
def对(l):
如果len(l)<2:
返回
对于范围内的i(透镜(l)-1):
收益率l[i],l[i+1]
收益率l[-1],l[0]
打印[a的abs(a-b),b成对([10,-12350])]

它不是一行,但可读性相当强。

将icecrime的答案与另一个python的可能性结合起来:

 print [numpy.linalg.norm(a-b) for a, b in zip(l, l[1:] + l[:-1])]

比我以前优雅多了!使用模而不是三元if/else很好。你需要计算距离(标量),这就得到了一个向量。@HennnyH-耶刚刚意识到:)ta。我刚刚编辑了你的(尝试修复),得到了与现在相同的表达式:)
 print [numpy.linalg.norm(a-b) for a, b in zip(l, l[1:] + l[:-1])]