を取得する理由IndexError
は、forループで反復するときにリストの長さを変更しているためです。基本的に、ここにロジックがあります...
#-- Build the original list: [0, 1, 2, ..., 19]
l = range(20)
#-- Here, the range function builds ANOTHER list, in this case also [0, 1, 2, ..., 19]
#-- the variable "i" will be bound to each element of this list, so i = 0 (loop), then i = 1 (loop), i = 2, etc.
for i in range(0,len(l)):
if i == something:
#-- So, when i is equivalent to something, you "pop" the list, l.
#-- the length of l is now *19* elements, NOT 20 (you just removed one)
l.pop(i)
#-- So...when the list has been shortened to 19 elements...
#-- we're still iterating, i = 17 (loop), i = 18 (loop), i = 19 *CRASH*
#-- There is no 19th element of l, as l (after you popped out an element) only
#-- has indices 0, ..., 18, now.
また、リストのインデックス付きセルにあるものではなく、リストのインデックスに基づいて「ポップ」の決定を行っていることにも注意してください。これは珍しいことです-それはあなたの意図でしたか?それとももっと似たような意味でしたか...
if l[i] == something:
l.pop(i)
さて、あなたの特定の例では(l[i] == i)
、これは典型的なパターンではありません。
リストを反復処理するのではなく、フィルター関数を試してください。これは組み込みです(他の多くのリスト処理機能のように:たとえば、マップ、ソート、リバース、zipなど)
これを試して...
#-- Create a function for testing the elements of the list.
def f(x):
if (x == SOMETHING):
return False
else:
return True
#-- Create the original list.
l = range(20)
#-- Apply the function f to each element of l.
#-- Where f(l[i]) is True, the element l[i] is kept and will be in the new list, m.
#-- Where f(l[i]) is False, the element l[i] is passed over and will NOT appear in m.
m = filter(f, l)
リスト処理関数は「ラムダ」関数と連携します。これは、Pythonでは簡単な無名関数です。したがって、上記のコードを次のように書き直すことができます...
#-- Create the original list.
l = range(20)
#-- Apply the function f to each element of l.
#-- Where lambda is True, the element l[i] is kept and will be in the new list, m.
#-- Where lambda is False, the element l[i] is passed over and will NOT appear in m.
m = filter(lambda x: (x != SOMETHING), l)
それを試してみて、それがどのように機能するかを見てください!