回答:
他の回答はシーケンスに対してのみ機能します。
イテラブルの場合、最初の項目をスキップするには:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
最後をスキップしたい場合は、次のようにします。
itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
# do work on 'prev' not 'car'
# at end of loop:
prev = car
# now you can do whatever you want to do to the last one on 'prev'
Pythonの最初の要素をスキップするには、次のように書くだけです。
for car in cars[1:]:
# Do What Ever you want
または最後のelemをスキップする
for car in cars[:-1]:
# Do What Ever you want
この概念はどのシーケンスにも使用できます。
最初のアイテムをスキップする最良の方法は次のとおりです。
from itertools import islice
for car in islice(cars, 1, None):
# do something
この場合のisliceは、開始点が1、終了点がNoneで呼び出され、イテレーターの終了を示します。
イテラブルの最後から項目をスキップできるようにするには、その長さを知る必要があります(リストでは常に可能ですが、反復できるすべてのものである必要はありません)。たとえば、islice(cars、1、len(cars)-1)は、carsリストの最初と最後の項目をスキップします。
islice、長さがわからなかったり、絶対に必要な以上のアイテムを一度にメモリに保存したりせずに、イテラブルの最初と最後で任意の数のアイテムをスキップする方法について説明しています。
islice渡されているものであるdeque、全体ではなくイテレータ、最後にスキップするアイテムの数の長さだけです。イテレータ全体をメモリに保存するわけではありません。
以下は、イテラブルの最初と最後から任意の数のアイテムをスキップする、より一般的なジェネレーター関数です。
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
使用例:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0ます。
skip(xrange(10000000), 1)はを使用するat_end=0ので、toのパラメーターdeque()はでありislice(it, 0)、これはのゼロ要素しか消費しませんit。これは多くのメモリを消費しません。
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
list変数名として使用しない
listは再バインドできます。あなたが理由ですべきではない、というよりはできません、それを使用しています。
@SvenMarnachの回答に基づくが、dequeを使用せずに少し単純に
>>> def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]
また、私のtimeit結果に基づいて、これはdequeソリューションよりわずかに速いことに注意してください
>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
list(skip(iterable,2,2))
"""
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
list(skip(iterable,2,2))
"""
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716
tee()ても、ジェネレーターのメモリ内にリスト全体が作成されますよね?(あなたのit1)
まあ、あなたの構文はそもそもPythonではありません。
Pythonのイテレーションは、構文を使用して、コンテナーのコンテンツ(厳密には、厳密にはイテレーターです)を超えていますfor item in container。この場合、コンテナーはcarsリストですが、最初と最後の要素をスキップしたいので、cars[1:-1](pythonリストはゼロから始まり、負の数は最後から数えて、:構文をスライスしています。
あなたが望んでいるのは
for c in cars[1:-1]:
do something with c
carsシーケンスである場合、あなたはただ行うことができます
for car in cars[1:-1]:
pass
more_itertoolsプロジェクトは、拡張しますitertools.islice負のインデックスを処理します。
例
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
したがって、イテラブルの最初の項目と最後の項目の間の要素をスライスしてエレガントに適用できます。
for car in mit.islice_extended(cars, 1, -1):
# do something
for n, i in enumerate(cars): if n!= 0: do something to iます。ロジックは、たとえばでターゲットにできる各値に「カウンター」を追加することですif n == some_value。この例では、最初のインスタンスを除いて、iの各インスタンスに対して何かを行います。