0

以下に示す2つのリストがあります。list.remove(x) 関数を使用して list1 と list2 の両方にあるファイルを削除しようとしていますが、リストの 1 つにはファイル拡張子があり、もう 1 つにはありません! 私のアプローチはどうあるべきですか!?

List1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
List2 = ['myfile', 'myfile2', 'myfile3']

#This is in short what I would like to do, but the file extensions throw off
#the tool!
for x in List2:
   List1.remove(x)

ありがとう!

4

2 に答える 2

8

リストからアイテムを削除するときに、リストをループするのは非常に危険です。ほとんどの場合、いくつかの要素をスキップすることになります。

>>> L = [1, 1, 2, 2, 3, 3]
>>> for x in L:
...     print x
...     if x == 2:
...         L.remove(2)
... 
1
1
2
3
3

また、それぞれ.removeが O(n) の複雑さであるため、非効率的です

新しいリストを作成してバインドし直す方が良いlist1

import os
list1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
list2 = ['myfile', 'myfile2', 'myfile3']
set2 = set(list2)  # Use a set for O(1) lookups
list1 = [x for x in list1 if os.path.splitext(x)[0] not in set2]

または「インプレース」バージョンの場合

list1[:] = [x for x in list1 if os.path.splitext(x)[0] not in set2]

コメントで説明されているように、真にインプレース バージョンの場合 - 余分な O(n) メモリを使用しません。O(n)時間で実行

>>> list1 = ['myfile.v', 'myfile2.sv', 'myfile3.vhd', 'etcfile.v', 'randfile.sv']
>>> p = 0
>>> for x in list1:
...     if os.path.splitext(x)[0] not in set2:
...         list1[p] = x
...         p += 1
... 
>>> del(list1[p:])
>>> list1
['etcfile.v', 'randfile.sv']
于 2013-07-02T00:41:29.597 に答える