2017-05-11 23 views
1

セットからエントリを削除する際に問題があります。リスト内の要素と一致する要素をセットから削除する

# Remove all out-of-stock items from our list 
# This is O(n^3), unfortunately. 
for x in oos: 
    for asin in asins: 
     if x == asin[0]: 
      del asin 

'asins' は、このように作成されたタプルの集合、次のとおりです。

asins.add(tuple((asin, c, s))) 

OOSリストです。私は 'oos'にも存在する 'asins'のすべてのエントリを削除しようとしています。残念ながら、「delin」は「asins」からエントリを削除しないので実際には機能しません。

答えて

1

これはジェネレータ式で簡単に実行できます。それは非効率的であってはいけませんが、私はそれを効率的とも呼んでいません。

asins = {t for t in asins if t[0] not in set(oos)} 

これは新しいセットを作成することに注意してください。これはおそらく、あなたがセットを反復してそれを所定の場所に変更することができないので、最高のものです。たとえば、del asinasins.remove(asin)に変更すると、RuntimeErrorとなります。

3

del asinこのように使用すると、ローカル変数asinは削除されますが、実際に参照されるオブジェクトは削除されず、特にセットに含まれるオブジェクトは削除されません。

代わりに、要素を削除するset.removeを呼び出す必要があります:

asins.remove(asin) 

はしかし、あなたが実際にそれから項目を削除するには、setをループする必要はありません。セットの利点のすべては、一定の時間アクセスを持つことで一定時間内にメンバーシップをチェックできるので、ループを上手く利用することはめったにありません。

複雑なタプルを保存しているため、最初のタプル要素で要素を識別するだけなので、ここではできません。あなたがすべきことは、より適切なコレクションに切り替えることです。

# convert your set of tuples to a dictionary 
# ideally, you would store the data like this in the first place 
asins = { asin[0]: asin for asin in asins } 

は次に、あなただけの次の操作を行うことができます:

for x in oos: 
    del asins[x] # here, you can use del 

平均的なケースではO(n)になり、あなたのケースでは、辞書が欲しいです。

+0

*削除されない*重複している最初の要素がある場合、これは機能しません。最初の要素をキーとしてリストを構築する 'defaultdict'のようなものが必要です。 –

+0

OPが最初のタプル値のみに基づいてアイテムを削除する場合、* all *はいずれにしても削除されます。 – poke

+0

私は*削除されていない値について話しています。重複キーは前のタプルをオーバーライドします。 –

関連する問題