0

短縮版:

私は拡張スライシングについて読んだばかりで、スライスのタプルをに渡すことができることを学びました__getitem__:

a[::3, 1::3]

それにもかかわらず、スライスを任意の関数に渡すことはできません (間違っている場合は修正してください)。したがって、これは失敗します。

f(::3, 1::3)

やや面倒な回避策は次の呼び出しsliceです。

f(slice(None, None, 3), slice(1, None, 3))

[]1.リスト、{}辞書とセット、または()ジェネレータとタプルのようなスライス リテラル (内包表記) はありますか? (たぶん<start, end, step>、または何でも)

2. きちんとしたスライス表記で任意の関数にスライスを渡すことは可能ですか?


長いバージョン (TL;DR):

リストの異なるスライスを合体させたい場合、つまり に評価されないこれらのスライスの最初の要素を見つけFalseたい場合、よく知られている非常に簡潔なスライス表記をこの関数に渡すことができればよいでしょう。解決策は次のようになりますが、これが賢明でないかどうかはわかりません。

#! /usr/bin/python3.3

class Array(list):
    class Coalescer:
        def __init__(self, array):
            self.array = array

        def __getitem__(self, slices):
            if not isinstance(slices, tuple):
                slices = (slices,)
            for s in slices:
                for e in self.array[s]:
                    if e: return e
            return None

    @property
    def coalesce(self):
        return Array.Coalescer(self)

a = Array ([0, 0, 2, 0, 3, 4, 0, 5, 6])

print(a.coalesce[:]) #2
print(a.coalesce[::3]) #None
print(a.coalesce[1::3]) #3
print(a.coalesce[::3, 1::3]) #3
a [6] = 42
print(a.coalesce[::3, 1::3]) #42

a.coalesce(slice(None, None, 3), slice(1, None, 3))私見、これはまたはよりも読みやすいですcoalesce(a, slice(None, None, 3), slice(1, None, 3))

3.これは実行可能なオプションですか、それとも使用しない方法の悪い例__getitem__ですか?

__getitem__4.いつ、どのように上書きするか、さらに重要なことに、いつ、どのように上書きしないかについてのガイドラインを提供するPEPまたはその他のドキュメントはありますか?

5. あなたの推定では、スライスの順序付けられたリストを結合する関数を実装する最も適切な方法はどれですか?

どうもありがとうございました。

4

1 に答える 1

2

最初に、@ JanneKarilaが提案したように、NumPyまたはpandasを使用して、受信するだけの関数を作成することをお勧めしますcoalesce(a[::3])

ただし、スライス可能で、スライスも実装する必要がある関数を持つオブジェクトを作成する必要がある場合は、Pandas ライブラリが行ったアプローチに従います。

  1. あなたはDataFrame(名前を気にしないでください)オブジェクトdfを持っていて、それを使ってスライスすることができますdf[1:3]

  2. ただし、特別なスライスが必要な場合は、別のオブジェクトを実装しました。これは、最初のオブジェクトへの参照を持ち、スライスも実装し、最初のオブジェクトの属性として使用できますdf.ix[3:5]

実装は次のようになります。

class SpecialSlicer(object):
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, ...):
       return sefl.obj[...]

class Array(object):
    def __init__(self):
       # do your stuff
       self.ss = SpecialSlicer(self)

    def __gettitem__(self, ...):
        return ....

だから今、あなたはできる:

 a = Array()
 a[3:4]
 a.ss[4:5]

しかし、この場合も、問題を正しく理解していれば、既にスライスされたオブジェクトを受け取るだけの関数を使用します。

于 2013-08-19T08:16:06.627 に答える