6

こんにちは、リスト内のすべての数値ペア間の距離を計算する必要があります。これには、最後の数値と最初の数値 (円) の間の距離も含まれます。

素朴に私はそのようなことをすることができます:

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」な方法はありますか?

4

6 に答える 6

4

これは小さな改善だと思います。ただし、これよりもクリーンな方法がある可能性があります。

print [abs(v - l[(i+1)%len(l)]) for i, v in enumerate(l)]
于 2013-04-30T13:47:18.400 に答える
2

別の方法:

print map(lambda x,y: abs(x-y), l[1:] + l[:1], l)
于 2013-04-30T13:57:58.820 に答える
1

大きな改善ではありません:

>>> [abs(a - b) for a, b in zip(l, l[1:] + l[:-1])]
[22, 362, 340]
于 2013-04-30T13:56:41.977 に答える
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])]

ワンライナーではありませんが、かなり読みやすいです。

于 2013-04-30T14:07:57.927 に答える
0

icecrime からの回答とこの回答を組み合わせると、別の Pythonic の可能性が提供されます。

 print [numpy.linalg.norm(a-b) for a, b in zip(l, l[1:] + l[:-1])]
于 2013-04-30T14:19:11.810 に答える
0

numpy を使用してよろしければ...

list(numpy.abs(numpy.ediff1d(l, to_end=l[0]-l[-1])))

これは、 long とうまくスケーリングします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
于 2013-04-30T13:54:20.040 に答える