【问题标题】:How to mask 2D list in Python?如何在 Python 中屏蔽二维列表?
【发布时间】:2018-05-27 08:35:15
【问题描述】:

我创建了一个 2D 列表,并在 the same type question 后面的 2D 列表上应用了蒙版。事实证明,发布的解决方案根本不适用于 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 列表。

【问题讨论】:

  • 那是因为compress 作用于列表的项目,而不是子列表的项目。所以一切都是真实的。

标签: python python-3.x


【解决方案1】:

一个简单的方法是重新实现 itertools.compress 实现的生成器表达式。

你把它变成语句,当给定位置的数据和选择器都是列表时,你在那个子列表上递归新的压缩函数:

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

【讨论】:

    【解决方案2】:

    肯定有一个更好的解决方案,涉及弄乱class 定义,但解决方法是这样的:

    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']]
    

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 2014-07-11
      • 1970-01-01
      • 2018-10-22
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      相关资源
      最近更新 更多