gpt4 book ai didi

python - 如何扩展、模仿或模拟 range 函数?

转载 作者:IT老高 更新时间:2023-10-28 20:34:00 25 4
gpt4 key购买 nike

我为字符范围做了一个小生成器函数:

>>> def crange(start, end):
... for i in range(ord(start), ord(end)+1):
... yield chr(i)
...

然后我可以这样做:

>>> print(*crange('a','e'))
a b c d e

耶!但这不起作用:

>>> crange('a','e')[::2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'generator' object is not subscriptable

这可行,但是是 O(n),不像 range 的 O(1):

>>> 'y' in crange('a','z')
True

这意味着从最多 110,000 个字符中搜索第 109,999 个字符大约需要 0.35 秒。 109999 in range(110000) 当然很快。

那时,我的第一个想法是简单地对范围进行子类化。不幸的是:

>>> class A(range):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'range' is not an acceptable base type

所以我想我必须以某种方式模仿它,允许我将字符作为参数传递,在内部像 range 一样工作,并产生字符。不幸的是,我不确定如何进行。我尝试了 dir():

>>> print(*dir(range), sep='\n')
__class__
__contains__
__delattr__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__getitem__
__gt__
__hash__
__init__
__iter__
__le__
__len__
__lt__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__reversed__
__setattr__
__sizeof__
__str__
__subclasshook__
count
index
start
step
stop

这让我可以看到里面有哪些函数,但我不确定它们在做什么,或者 range 如何使用它们。我查找了 range 的源代码,但它是 C 语言的,我不知道在哪里可以找到它的 Python 包装器(它确实有一个,对吗?)。

我从这里去哪里,我应该去那里吗?

最佳答案

At that point, my first thought was to simply subclass range.

range是 Python2 中的一个函数和 Python3 中的一个“最终”类( more info here )——在这两种情况下都不是你可以子类化的东西。您需要创建一个类 crangeobject 延伸作为基本类型。

class crange(object):

And this works, but is O(n), unlike range's O(1)

在 Python 3 中,有一个 __contains__ 您将为对象定义的方法。

For objects that don’t define __contains__(), the membership test first tries iteration via __iter__(), then the old sequence iteration protocol via __getitem__(), see this section in the language reference.

这允许 Python 确定值是否在您的范围内,而无需实际枚举范围。

举个简单的例子,如果您的范围是 1 到 1,000,000,确定 23546 是否在该范围内 (1 < 23546 < 1000000) 很简单。当然,实际的实现要复杂一些,并且增加了处理步长等的能力。

关于:

Yay! But this doesn't work: >>> crange('a','e')[::2]

在这种情况下,您需要定义 __getitem__在你的对象上。以下是一些所需方法的示例:

class crange(object):
def __init__(self, start, end, step=1):
# initialize your range object
self.start = start
self.end = end
self.step = step

def __iter__(self):
# enable iteration over your object
# (assume step size is 1)
for i in range(ord(self.start), ord(self.end)+1):
yield chr(i)

def __getitem__(self, i):
# enable accessing items in your range by index
# also enable crange('a','e')[::2]
# (assuming step size of 1)
if isinstance( i, slice ):
# implement slicing
else:
return chr(ord(self.start) + i)

def __contains__(self, char):
# enable O(1) determination of whether a value is in your range
# (assume step size is 1)
return ord(self.start) <= ord(char) < ord(self.end)

def __len__(self):
# return length (assuming step size of 1)
return ord(self.end) - ord(self.start)

关于python - 如何扩展、模仿或模拟 range 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30362799/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com