嗨我需要计算列表中每个数字对之间的距离,包括最后一个和第一个之间的距离(它是一个圆圈)。
天真地我可以这样做:
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]
有更优雅和“pythonic”的方式吗?
答案 0 :(得分:3)
我认为这是一个小改进。可能会有比这更清洁的方式:
print [abs(v - l[(i+1)%len(l)]) for i, v in enumerate(l)]
答案 1 :(得分:2)
另一种方法:
print map(lambda x,y: abs(x-y), l[1:] + l[:1], l)
答案 2 :(得分:1)
不是一个巨大的改进:
>>> [abs(a - b) for a, b in zip(l, l[1:] + l[:-1])]
[22, 362, 340]
答案 3 :(得分:0)
如果你愿意使用numpy ......
list(numpy.abs(numpy.ediff1d(l, to_end=l[0]-l[-1])))
这可以很好地扩展l
。不转换为列表或从列表转换将会加快速度(通常可以使用numpy数组代替列表)。
或者您可以使用numpy.roll
自行构建:
list(numpy.abs(l - numpy.roll(l, -1)))
一些时间:
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
答案 4 :(得分:0)
在这种情况下,它可能不如其他答案好,但如果用作更大代码库的一部分,定义一个迭代器可能很有用,该迭代器返回列表上的项目对,例如:
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])]
这不是一个单行,但相当可读。
答案 5 :(得分:0)
将来自icecrime的答案与this answer结合起来提供了另一种pythonic可能性:
print [numpy.linalg.norm(a-b) for a, b in zip(l, l[1:] + l[:-1])]