2016-12-02 1 views
1

私はリストリストをPythonの関数に渡すときに、リスト内の要素を「隠す」方法は?

myList = [a,b,c,d,e] 

と機能

def doSomething(list): 
    #Does something to the list 

を持っていると私は繰り返し、このように関数を呼び出したいとします

doSomething([b,c,d,e]) 
doSomething([a,c,d,e]) 
doSomething([a,b,d,e]) 
doSomething([a,b,c,e]) 
doSomething([a,b,c,d]) 

心に来る最初の事でしょうこのようなもの:

for x in range(0,len(myList)): 
    del myList[x] 
    doSomething(myList) 

しかし、これは実際には機能しません。なぜなら、delを呼び出すたびに要素を実際に削除するからです。私は、関数を呼び出すたびに要素を「隠す」ようにしています。これを行う方法はありますか?

+0

リストをコピーして削除しますか? –

+0

@AndrasDeak私はそれが方法かもしれないと思ったが、大きなリストの場合、私が関数を呼び出すたびにリストをコピーしている。リストもまたコピーするには? –

+0

大規模なリストの場合、はい、それは非効率的かもしれません。単純な(ネストされていない)リストのコピーは 'cpy = myList [:]'と同じくらい簡単です。あなたは、myList [:k] + myList [k + 1:] 'コーナーケースを見て、要素インデックス' k'を無視することができます。しかし、これもあなたのためのリストを作成します。 –

答えて

1

通常、インデックスをループするのは良い考えではありませんが、この場合、特定のインデックス(繰り返し)で要素を削除してインデックスをループするのが実際には1回だけ適切であるようです。

この目的のためにlist.popを使用することができますが、ループの各ターン(リストをコピーするために1回、i番目の要素を削除するために1回)に余分なO(N)操作が必要です。

for i in range(len(lst)): 
    new_list = lst[:] # lst.copy() in python3.x 
    new_list.pop(i) 
    doSomething(new_list) 

:私達は...私たちがコピーしている間に要素を除去することによって、異なっしかしこれは単純なアプローチよりも高速になることが保証されていないことを

for i in range(len(lst)): 
    new_list = [x for j, x in enumerate(lst) if j != i] 
    doSomething(new_list) 

注を行うことができます素朴なアプローチは、.popで実行する必要のあるインデックス作成をCコードにプッシュするという利点があります。これは、Pythonの比較よりもはるかに速くなります。

2

あなたはこのためにitertools.combinationsを使用することができます。

import itertools 

for sublist in itertools.combinations([a, b, c, d, e], 4): 
    # 4 is the number of elements in each sublist. 
    # If you do not know the length of the input list, use len() - 1 
    doSomething(sublist) 

これはsublistタプルを行います。リストにする必要がある場合は、list()に電話してdoSomething()に渡すことができます。

あなたはdoSomething()呼び出しが行われる順序を気にしている場合、あなたはそれではなく、最後の要素の最初の要素を削除することで始まるように、繰り返しの順序を逆にしたいと思うでしょう:

for sublist in reversed(list(itertools.combinations([a, b, c, d, e], 4))): 
    doSomething(sublist) 

このすべてのサブリストが一度に1つではなく正面で生成されなければならないため、効率的ではありません。コメントの中のmgilsonは、入力リストを逆順にしてから各サブリストを逆順にすることを提案しています。これはより効率的ですが、コードを読みにくくなる可能性があります。

+0

私もこれを提案することを考えました。私はこれとナイーブなアプローチのタイミングをどう比較するのか興味があります。 – mgilson

+1

関数の実行順序が問題になるのではないかと疑問です –

+1

入力を取り消してから( '[e、d、c、b、a]')、サブリストを 'doSomething'に渡すことができますか?それはリストを前面に出さないようにするでしょう。 – mgilson

関連する問題