例としてリストを見てみましょう:
a = [255, 255, 1, 255, 255, 255, 1, 2, 255, 255, 2, 255, 255, 3, 255, 3, 255, 255, 255]
255
その中の特別な値です。プレースホルダーです。
リスト内のプレースホルダーの一部を置き換えるジェネレーターを作成しました。期待どおりに動作します。
しかし、最初のプレースホルダー[255, 255
と最後のプレースホルダーを処理255, 255, 255]
してそのまま生成する必要はありません。
そこで、ジェネレーターを修正して解決しようとしました。
パイソン 2.7
from __future__ import print_function
from itertools import tee, izip, ifilterfalse
def replace(iterable,placeholder=255):
it = enumerate(iterable) #the position is needed for the logic for the middle of the list
it = ifilterfalse(lambda x: x[1]==placeholder, it) #create an iterator that deletes all the placeholders
for i,(left,right) in enumerate(window(it,2)): #Slide through the filtered list with the window of 2 elements
if i==0: #Leaving the beginning placeholders intact
for j in range(left[0]):
yield placeholder
#SOME LOGIC FOR THE MIDDLE OF THE LIST (it works well)
#Need to leave the trailing placeholders intact.
コードの理解を容易にするためだけにリストに変換された中間値:
>>>iterable
[255,1,255,255,1,255,255,255,2,2,255,255,255,2,2,3,255,255,255,3,255,255]
>>>it = enumerate(iterable)
[(0, 255), (1, 1), (2, 255), (3, 255), (4, 1), (5, 255), (6, 255), (7, 255), (8, 2), (9, 2), (10, 255), (11, 255), (12, 255), (13, 2), (14, 2), (15, 3), (16, 255), (17, 255), (18, 255), (19, 3), (20, 255), (21, 255)]
>>>it = ifilterfalse(lambda x: x[1]==placeholder, it)
[(1, 1), (4, 1), (8, 2), (9, 2), (13, 2), (14, 2), (15, 3), (19, 3)]
>>>list(enumerate(window(it,2)))
[(0, ((1, 1), (4, 1))), (1, ((4, 1), (8, 2))), (2, ((8, 2), (9, 2))), (3, ((9, 2), (13, 2))), (4, ((13, 2), (14, 2))), (5, ((14, 2), (15, 3))), (6, ((15, 3), (19, 3)))]
したがって、ご覧のとおりlist(enumerate(window(it,2)))
、先頭の非プレースホルダー値のインデックスが含まれて(0, ((**1**, 1), (4, 1))),
いますが、最初のイテレータが持っていた末尾のプレースホルダーの数に関する情報は含まれていません。最後の非プレースホルダーのインデックスのみを持つlist(enumerate(window(it,2)))
この値で終わります。(6, ((15, 3), (**19**, 3)))
プレースホルダー値。プレースホルダーがいくつ残っているかはわかりません。
it = enumerate(iterable)
によって最初に生成された値に保持される初期イテレータ値の位置を生成することに依存して、主要なプレースホルダーを処理することができましたifilterfalse
。
しかし、末尾のプレースホルダーを使用して同じことを行う方法を見つけるのにかなりの時間を費やしました。問題はifilterfalse
、 の最後のプレースホルダー値を飲み込むだけでenumerate(iterable)
あり、それらにアクセスする方法がわかりません (最初に生成された の値ifilterfalse
に の値のインデックスが含まれていたため、主要なプレースホルダーが可能でしたenumerate(iterable)
)。
質問
末尾のプレースホルダーを処理するためにこのコードを修正する最良の方法は何ですか?
どうしてもコードを作ることが目的ではないので(別の手法で作ったことあります)、完全に書き直すのではなく、コードを少しいじって解決したいと思います。
実際の作業というよりはトレーニングです。
追加情報
window
ここからのコードです。
私のコードは、@nye17 によるこの回答とほぼ同じです。しかし、このコードでは、作成者が最初のリストをインプレースで変更しています。そして、そのコードの結果のリストと同じ値を生成するジェネレーターを作成したいと考えています。
さらに、ジェネレーターがリストだけでなく、イテラブルをパラメーターとして受け入れるようにします (たとえば、ファイルから値を 1 つずつ読み取るイテレーターを受け入れる場合があります)。パラメータとしてリストのみを使用すると、リストを最後からスキャンできるため、タスクが簡単になります。
これは、私が人生で解決しなければならない本当の課題ではありません。あくまで研修用です。
完全なコード http://codepad.org/9UJ9comY