切片命名元组

Slicing a namedtuple

我有一个要切片的命名元组:

>>> from collections import namedtuple
>>> coords = namedtuple('coords', ['lng', 'lat', 'alt'])
>>> everest = coords(86.92, 27.97, 8848)

所以现在我可以轻松访问属性

>>> everest.alt
8848

但是,当我只想使用经度和纬度时(例如在某些几何算法中),我将对元组进行切片

>>> flag = everest[:2]
>>> flag.lat
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'lat'

我想知道是否可以对 namedtuple 进行切片并单独保留切片部分的属性。

您可以为此编写一个辅助方法,将自定义 __getitem__ 附加到创建的命名元组 class。 __getitem__ 每次都会创建一个新的 class,但使用 slice

的参数数量较少
from collections import namedtuple


def namedtuple_with_slice(name, args):
    cls = namedtuple(name, args)
    def getitem(self, index):
        # `type(self)` can result in issues in case of multiple inheritance.
        # But shouldn't be an issue here.
        value = super(type(self), self).__getitem__(index)
        if isinstance(index, slice):
            cls = namedtuple(name, args[index])
            cls.__getitem__ = getitem
            value = cls(*value)
        return value
    cls.__getitem__ = getitem
    return cls

演示:

>>> coords = namedtuple_with_slice('coords', ['lng', 'lat', 'alt'])
>>> everest = coords(86.92, 27.97, 8848)
>>> everest[:1]
coords(lng=86.92)
>>> everest[:2]
coords(lng=86.92, lat=27.97)    
>>> everest[:3]
coords(lng=86.92, lat=27.97, alt=8848)    
>>> everest[:3][:2]
coords(lng=86.92, lat=27.97)