2010-12-12 15 views
0

私がやりたかったのは、リストを検索して値を削除することでした。次のコードの複雑さを減らす

だから私は最初それが値を探し、それを削除し、後方の値の残りの部分をプッシュするため、次のコード

for x in range(10): 
    if x in list1: 
     list1.remove(x) 

はオーダーのこの機能は、(N^2)〜い書きました?

また

try: 
    for x in range(10): 
    list1.remove(x) 
except ValueError: 
    # make it go back to next iteration 
+1

2番目のケースでは、forループを使用しないでください。 – extraneon

+2

質問には関係ありませんが、変数名には組み込みの名前を使用しない方がよいでしょう。 Pythonはこれを可能にしますが、あなたがしていることを正確に知らなければ、意図しない結果を招く可能性があります。 –

+0

@Tim:それは悪化する可能性がありますが、非常に真実です(動的スコープでは - eeeevil);) – delnan

答えて

2

これはfilter()のための仕事のように聞こえる:

>>> filter(lambda x: not x in (4, 5, 7), xrange(10)) 
[0, 1, 2, 3, 6, 8, 9] 

更新:私はlist comprehensionを使用してリストを作成するもう一つの例:

>>> filter(lambda x: not x[0] in (4, 5, 7), [[a] for a in xrange(10)]) 
[[0], [1], [2], [3], [6], [8], [9]] 
+0

ちょっと、私のxがa = [[1]、[2]、[2]]のようなネストされたリストに入っているなら、どうしたらいいのですか? xrange作業の代わりに?? –

+0

これは新しいリストを作成しますが、既存の要素(または例のイテレータ)の各要素を、削除する要素の別のシーケンスの各要素と比較して調べています。それは 'filter()'を使っているため、 'for'よりも少し速いかもしれませんが、それはずっと効率的ではないでしょう。 – martineau

+0

私は完全にそのプロパティを知っていますが、後者はもう1つの例です。 –

5

使用するtry/exceptを使用して次数nでこれを有効にする方法があります:(

L = [x for x in L if x not in removal_list] 

removal_listは、任意のコンテナすることができますが、あなたがセットを使用している場合は)あなたはO(n)(n = len(L))を達成することができます。

+0

+1だが '/(.*)removal_list \\]/removal_set = set \\(removal_list \\)\ n \ 1 removal_set \\] /'。このような単純な変更で 'O(n ** 2)'から 'O(n)'にしたいのはなぜですか? – delnan

+0

'L = [xが削除リストにない場合はxのLのxはLです]'は無効な構文です。 – martineau

+0

@martineau removal_listがリストであることを前提にテストしたときに正しいです..... –

0

ニシキヘビない私の面積が、いくつかの春心に。まず、リストをどのくらい大きくするのですか。何回か繰り返します。それが大きければ、物事を回すのが良いアイデアかもしれないので、あなたはそれを一度しか反復しません。

第2に、PythonがJavaのようなものなら、良いコードのためのルールがあります - プロセスフローに例外を使わないでください。これはあなたの2番目の提案を排除します。それはまた、それがひどく実行する可能性があります。

+0

なぜそれはひどく実行すると言うのですか?オーバーヘッドの点で??? –

+0

@Derek:Pythonでは、最大値は「許可よりも許しを求める方が良い」ということです。 2番目の例(ループ内の 'try'を使用)はPythonスタイルであり、かなり効率的です。 –

+0

@Derek Javaの「プロセスフローに例外を使用しないでください」を明確にしてください。どうして? – khachik

1

スライスの交換:

ジョヴァンニ・バホが示唆同様
a[:] = (l for l in a if l not in set(list_of_removable)) 
0

、リスト内包表記は涼しいですが、一度だけの結果を使用しますと仮定すると、発電機は、さらに良いです:

l = [1,23,2,24,3,26,1] 
(x for x in l if x not in xrange(10)) 

xrange()がありますジェネレータも同様です。range() 2回以上結果を使用したい場合は、

[x for x in l if x not in xrange(10)] 
0

元の質問に答えるには:list-to-remove-elements-fromの各要素とlist-containing-removable-elementsの各要素を比較しなければならないという事実を回避することはできません。その意味では、このコードのすべてのバージョンはO(N^2)です(各リストに任意に多くの要素があると仮定して)。さまざまな構文を使用してループを隠すことができます(多くの場合、より多くのバイトコードを解釈するのではなく、インタープリタのCコードでループを行うことができるため、より速くなります)が、ループは依然として(そして、定数分析はbig-O分析によって無視されることを忘れないでください)。

関連する問題