0

リストを反復処理するPython構文はfor x in y:、ポインターが現在正しい要素を何とか覚えている必要がありますか?私が頼らずにこれを解決しようとしているので、どのようにその価値にアクセスしますか? for index, x in enumerate(y):

私がこれをやりたいという技術的な理由は、enumerate()既存の「ポインタ」に何らかの形でアクセスしている間はパフォーマンスが低下すると想定しているためです。ただし、回答から、このポインタは非常にプライベートでアクセスできないことがわかります。

これを実行したかった機能的な理由は、現在の要素のfloat値が「目的の」float範囲から遠く離れている場合に、たとえば100要素をスキップできるようにするためです。

- 答え -

これを解決する方法は次のとおりです(純粋な概略例)。

# foo is assumed to be ordered in this example
foo = [1,2,3,4,5,6....,99,100]
low = 60
high = 70
z = iter(foo)
for x in z:
    if x < low-10
        next(islice(z,10,10),None)
    if x > high
        break
4

4 に答える 4

7

それはいけません。Python反復プロトコルforを使用します。これは、リストの場合、プライベートイテレータオブジェクトを作成することを意味します。そのオブジェクトは、リスト内の位置を追跡します。

を使用してイテレータを明示的に作成した場合でもiter()、現在の位置はそのオブジェクトのパブリックプロパティではありません。

>>> list_iter = iter([])
>>> list_iter
<listiterator object at 0x10056a990>
>>> dir(list_iter)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__length_hint__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'next']

反復プロトコルのポイントは、境界なしで継続するシーケンスであっても、まったく同じ方法で任意のシーケンスを処理できることです。位置を持たないシーケンスジェネレータを作成するのは簡単です:

def toggle():
    while True:
        yield True
        yield False

そのジェネレーターは、反復するときに値Trueと値を切り替えます。Falseそこにはシーケンス内に位置がないため、位置を公開するポイントもありません。

に固執するだけenumerate()です。しenumerate()なければならないのは、カウンターを保持することだけです。ラップされたイテレータ内の位置をまったく保持しません。その整数をインクリメントしても、パフォーマンスやメモリのコストはそれほど高くありません。

enumerate()基本的にこれであり、Cで実装されています:

def enumerate(sequence, start=0):
    n = start
    for elem in sequence:
        yield n, elem
        n += 1

これはCで実装されているため、いつでも元のイテレータの属性を読み取ろうとするよりも優れており、各反復でより多くのバイトコード操作が必要になります。

于 2013-03-22T14:03:55.750 に答える
1

いいえ、現在のインデックスを追跡するように強制されていない、基になるイテレータを使用します。

手動でカウンターを固定しない限り、これは不可能です。

idx = 0
for x in y:
    idx+=1
    # ...

だから、enumerate()

于 2013-03-22T14:01:24.477 に答える
1

その「ポインタ」値は、イテレータを作成したものの内部にあります。これはリスト(インデックス付けできるもの)である必要はないので、本当に「インデックス」が必要な場合は、列挙型を使用する必要があります。

于 2013-03-22T14:02:25.710 に答える
1

この情報はイテレータの内部にあり、アクセスできません。イテレータプロトコルの説明については、ここを参照してください。基本的に、イテレータの唯一の公的に利用可能なメンバーは、範囲が使い果たされると例外next()を発生させるものです。StopIteration

その上、enumerateかなり効率的です。書くのと同じです

i = -1
for x in y:
  i += 1
  # do something with x and i
于 2013-03-22T14:03:38.310 に答える