2017-12-13 3 views
3

2Dリストを作成し、2Dリストにマスクを適用した後、the same type questionとしました。投稿されたソリューションは、2Dリストでは機能しませんでした。Pythonで2Dリストをマスクする方法は?

from itertools import compress 
class MaskableList(list): 
    def __getitem__(self, index): 
     try: return super(MaskableList, self).__getitem__(index) 
     except TypeError: return MaskableList(compress(self, index)) 

aa=[['t', 'v'], ['a', 'b']] 
aa=MaskableList(aa) 
print(aa) 
>>> [['t', 'v'], ['a', 'b']] 

mask1=[[1,0],[0,1]] 
print(aa[mask1]) 
>>> [['t', 'v'], ['a', 'b']] 

mask2=[1,0,0,1] 
print(aa[mask2]) 
>>> [['t', 'v']] 

それが2Dリストをマスキングするために働く、クリーンで効率的な方法:ここで は、コードと出力されます。

+1

これは、 'compress'がサブリストの項目ではなくリストの項目に作用するためです。だからすべてが真実です。 –

答えて

3

簡単な方法。

あなたは文にそれを回すと、指定した位置のデータとセレクタの両方がリストされているとき、あなたはそのサブリストの上に、新しい圧縮機能を再帰:

from collections import Iterable 
def compress_rec(data, selectors): 
    for d, s in zip(data, selectors): # py3 zip is py2 izip, use itertools.zip_longest if both arrays do not have the same length 
     if isinstance(d, Iterable) and isinstance(s, Iterable): 
      yield compress_rec(d, s) 
     else: 
      yield d 

それはどんな次元で動作するでしょうそのようにアレイ。

HTH

+0

多くの感謝!それはうまくいった。 – Cheng

2

ありclass定義をいじり含まれ、より良い解決策は確かにあるが、回避策はこのようになります:あなたはそれがitertools.compress実装するジェネレータ式を再実装することです行うことができ

from itertools import compress 
class MaskableList(list): 
    def __getitem__(self, index): 
     try: 
      return super(MaskableList, self).__getitem__(index) 
     except TypeError: 
      return MaskableList(compress(self, index)) 

aa = [['t', 'v'], ['a', 'b']] 
mask1 = [[True, False], [False, True]] 

new = [MaskableList(sublist)[submask] for sublist, submask in zip(aa, mask1)] 
print(new) # -> [['t'], ['b']] 
+0

多くの感謝!それはうまくいった。 – Cheng

関連する問題