广义区间长度的计算

2024-09-30 01:32:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我开始编写一个名为grange的类,作为一个通用范围——创建一个日期范围,等等

计算整数范围的长度很容易:(stop - start)//step

len(range(0, 8, 2))->;(8 - 0)//2->;(8)//2->;4

当然,处理消极步骤和start>;stop有点棘手,但总体思路是正确的。你知道吗

但是当我从具体的整数领域转移到抽象的“事物”领域时,我的思想开始融化。你知道吗

让我们假设几件事:

  • Start、Stop和Step都定义了__add____sub____truediv__,它们在对象之间是可互操作的。

  • 当像这样组合时:(start - stop + step)//step我们得到一个空的数字(int,float,complex,等等)。

  • 开始、停止或步骤+1可能引发类型错误,即timedelta(days=1) + 1

以下是我目前的情况:

def __len__(self):
    if self.stop is None:
        # 10/10 wish float('inf') was returnable
        raise TypeError("Infinite Range!")
    try:
        # factor in self.step to compensate to include start position
        if self._has_neg_step:
            calc = self.start - self.stop - self.step
        else:
            calc = self.stop - self.start + self.step
        # counteract float and negative steps
        return int(abs(calc//self.step))
    except (TypeError, ValueError):
        # throw a hail mary!
        # seems dangerous but should be *alright* since
        # bail out on infinite sequence case
        return len(list(iter(self)))

这个很适合约会!你知道吗

start, stop = datetime(2015, 3, 1), datetime(2015, 3, 8)
step = timedelta(days=2)
assert len(grange(start, stop, step)) == 4

但对于整数。。。你知道吗

assert len(grange(0,8,1)) == 8, len(grange(0, 8, 1))
AssertationError: 9

最初,我曾考虑在一个问题上提出一个抽象概念:

self._one = step//step

所以我可以做:

(self.stop - self.start - self.step + self.one)//self.step

一个事物被它自己分开就是一个!谢谢小学!但是有一个问题:timedelta(days=2)//timedelta(days=2) == 1不是timedelta(days=1)

原来我忘了x unit/x unit也会取消单位部分的部分。至少是时间差。谁知道其他物体会做什么?你知道吗

我不相信,通过实现,一个通用算法是可能的(或者甚至可能在所有!)但直接去:len(list(iter(self)))似乎是浪费,但这似乎也是唯一万无一失的解决方案。你知道吗

一种折衷方法似乎是使用len(list(iter(self)))计算一次长度并将其存储在属性中:

# works because Python will bypass __getattribute__ when len is called.
@property
def __len__(self):
    if self.stop is None:
        raise TypeError('Infinite range')
    if not hasattr(self, '__len__'):
        self.__len__ = len(list(iter(self))
    return self.__len__

这消除了许多关于传递对象的假设。你知道吗

有什么建议吗?你知道吗


Tags: gtselflenifisstep整数float
1条回答
网友
1楼 · 发布于 2024-09-30 01:32:27

问题与类型无关:在len(grange(0,8,1))中,8也被计算为长度(因此0,1,2,3,4,5,6,7,8是9个数字)。这不是发生在你的日期的例子,因为你不能得到8从1开始一步2。你知道吗

那么如果calc是一个倍数(乘法?英语不是我的母语)的步骤,(正常div,不是truediv)减去长度1。你知道吗

你的len博士的行为就好像田庄包括了止损,但你希望它排除止损,从而产生意想不到的结果。你知道吗

相关问题 更多 >

    热门问题