web-dev-qa-db-ja.com

Python slice how-to、私はPython sliceを知っていますが、組み込みのスライスオブジェクトをどのように使用できますか?

組み込み関数sliceの使用方法と使用方法を教えてください。
私が知っているPythonicスライスの直接的な方法-l1[start:stop:step]。スライスオブジェクトがあるかどうかを知りたいのですが、どのように使用しますか?

63
necromancer

[start:end:step]表記を使用する場合に使用するのと同じフィールドでsliceを呼び出して、スライスを作成します。

sl = slice(0,4)

スライスを使用するには、リストまたは文字列へのインデックスのようにスライスを渡します。

>>> s = "ABCDEFGHIJKL"
>>> sl = slice(0,4)
>>> print(s[sl])
'ABCD'

固定長のテキストフィールドのファイルがあるとします。スライスのリストを定義して、このファイルの各「レコード」から値を簡単に抽出できます。

data = """\
0010GEORGE JETSON    12345 SPACESHIP ST   HOUSTON       TX
0020WILE E COYOTE    312 ACME BLVD        TUCSON        AZ
0030FRED FLINTSTONE  246 GRANITE LANE     BEDROCK       CA
0040JONNY QUEST      31416 SCIENCE AVE    PALO ALTO     CA""".splitlines()


fieldslices = [slice(*fielddef) for fielddef in [
    (0,4), (4, 21), (21,42), (42,56), (56,58),
    ]]
fields = "id name address city state".split()

for rec in data:
    for field,sl in Zip(fields, fieldslices):
        print("{} : {}".format(field, rec[sl]))
    print('')

プリント:

id : 0010
name : GEORGE JETSON    
address : 12345 SPACESHIP ST   
city : HOUSTON       
state : TX

id : 0020
name : WILE E COYOTE    
address : 312 ACME BLVD        
city : TUCSON        
state : AZ

id : 0030
name : FRED FLINTSTONE  
address : 246 GRANITE LANE     
city : BEDROCK       
state : CA

id : 0040
name : JONNY QUEST      
address : 31416 SCIENCE AVE    
city : PALO ALTO     
state : CA
85
PaulMcG

シーケンスに続く角かっこは、かっこ内の内容に応じて、インデックス付けまたはスライスを示します。

_>>> "Python rocks"[1]    # index
'y'
>>> "Python rocks"[1:10:2]    # slice
'yhnrc'
_

これらのケースは両方とも、シーケンスの__getitem__()メソッド(または等号の左側にある場合は__setitem__())によって処理されます。インデックスまたはスライスは、単一としてメソッドに渡されます。引数、およびPython=これは、スライス表記(この場合は_1:10:2_)をスライスオブジェクトslice(1,10,2)に変換することによって行われます。

したがって、独自のシーケンスのようなクラスを定義する場合、または別のクラスの___getitem___または___setitem___または___delitem___メソッドをオーバーライドする場合、intかどうかを判断するためにインデックス引数をテストする必要がありますまたはslice、およびそれに応じて処理します。

_def __getitem__(self, index):
    if isinstance(index, int):
        ...    # process index as an integer
    Elif isinstance(index, slice):
        start, stop, step = index.indices(len(self))    # index is a slice
        ...    # process slice
    else:
        raise TypeError("index must be int or slice")
_

sliceオブジェクトには、startstopstepの3つの属性と、1つの引数、オブジェクトの長さを取り、3-Tuple:_(start, stop, step)_を返す1つのメソッドindicesがあります。

33
Don O'Donnell
>>> class sl:
...  def __getitem__(self, *keys): print keys
...     
>>> s = sl()
>>> s[1:3:5]
(slice(1, 3, 5),)
>>> s[1:2:3, 1, 4:5]
((slice(1, 2, 3), 1, slice(4, 5, None)),)
>>>

slice 関数は、 スライスオブジェクト を返します。スライスオブジェクトはPythonの内部タイプの1つであり、読み取りパフォーマンス用に最適化されています。その属性はすべて読み取り専用です。

デフォルトの動作を変更したい場合は、sliceを変更すると便利です。たとえば、 lxml はスライス表記を使用してDOM要素にアクセスします(ただし、自分でどのように実行したかは確認していません)。

3
Tim McNamara

変数に基づいて文字列をサブセットする に答えようとしている間、numpyにはスライスオブジェクトを定義するための構文的に素晴らしい方法があることを思い出しました:

>>> import numpy as np
>>> s = "The long-string instrument is a musical instrument in which the string is of such a length that the fundamental transverse wave is below what a person can hear as a tone."
>>> z = np.s_[18:26]  # in this case same as slice(18, 26, None)
>>> s[z]
'strument'

ここで解決される問題は、後で使用するためにスライスを変数に保存する方法、およびnp.s_はまさにそれを可能にします。はい、組み込みではありませんが、元の質問がここにリダイレクトされたので、私の答えもここに属しているように感じます。また、numpyは、Python、IIRCに高度なスライス機能が追加された理由の1つでした。

より複雑な「スライス」の例:

>>> data = np.array(range(6)).reshape((2, 3))
>>> z = np.s_[:1, 1:2]
>>> data[z]
array([[1]])
>>> data
array([[0, 1, 2],
       [3, 4, 5]])
>>> z
(slice(None, 1, None), slice(1, 2, None))

ここで、zはスライスのタプルです。

1
Roman Susi