首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的循环范围

Python中的循环范围
EN

Stack Overflow用户
提问于 2016-12-05 08:48:45
回答 5查看 4.7K关注 0票数 3

如何在Python中实现循环范围对象

例如:

设S是一个圆形空间模2^3 (范围[0,2^3))。我想要生成这样一个range对象:

代码语言:javascript
复制
crange(3, 7, 2 ** 3) => a range object [3, 4, 5, 6]
crange(7, 3, 2 ** 3) => a range object [7, 0, 1, 2]

我试过这个:

代码语言:javascript
复制
def crange(start, stop, modulo):
    if start > stop:
        return range(start, modulo) or range(stop)
    else:
        return range(start, stop)

但我不能输入bigint到crange,例如crange(8, 2, 2 ** 160)

代码语言:javascript
复制
OverflowError: Python int too large to convert to C ssize_t
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-12-05 15:25:19

非常感谢各位。

我实现了我想要的crange (参考@Ni和@J.F.Sebastian)。

代码语言:javascript
复制
import math


class crange:
    def __init__(self, start, stop, step=None, modulo=None):
        if step == 0:
            raise ValueError('crange() arg 3 must not be zero')

        if step is None and modulo is None:
            self.start = 0
            self.stop = start
            self.step = 1
            self.modulo = stop
        else:
            self.start = start
            self.stop = stop
            if modulo is None:
                self.step = 1
                self.modulo = step
            else:
                self.step = step
                self.modulo = modulo

    def __iter__(self):
        n = self.start
        if n > self.stop:
            while n < self.modulo:
                yield n
                n += 1
            n = 0
        while n < self.stop:
            yield n
            n += 1

    def __contains__(self, n):
        if self.start >= self.stop:
            return self.start <= n < self.modulo or 0 <= n < self.stop
        else:
            return self.start <= n < self.stop

我得到了以下输出:

代码语言:javascript
复制
>>> print(list(crange(start=7, stop=3, modulo=2 ** 4)))
[7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2]
>>> print(3 in crange(start=7, stop=3, modulo=2 ** 4))
False
>>> print(7 in crange(start=7, stop=3, modulo=2 ** 4))
True
>>> print(list(crange(start=3, stop=7, modulo=2 ** 4)))
[3, 4, 5, 6]
>>> print(3 in crange(start=3, stop=7, modulo=2 ** 4))
True
>>> print(7 in crange(start=3, stop=7, modulo=2 ** 4))
False
票数 3
EN

Stack Overflow用户

发布于 2016-12-05 09:03:21

试试这个:

代码语言:javascript
复制
def crange(start, stop, modulo):
    result = []
    index = start
    while index != stop:
        result.append(index)
        index = (index + 1) % modulo
    return result

如果您知道您的列表可能太长,则可以使用生成器来生成必需序列:

代码语言:javascript
复制
def crange(start, stop, modulo):
    index = start
    while index != stop:
        yield index
        index = (index + 1) % modulo
票数 3
EN

Stack Overflow用户

发布于 2016-12-05 09:05:09

通过创建自己的生成器,可以避免在内存中使用范围和存储庞大的列表:

代码语言:javascript
复制
def crange(start, end, modulo):
    if start > end:
        while start < modulo:
            yield start
            start += 1
        start = 0

    while start < end:
        yield start
        start += 1

print list(crange(3, 7, 2 ** 3))
print list(crange(7, 3, 2 ** 3))
print next(crange(8, 2, 2 ** 160))

该代码输出:

代码语言:javascript
复制
[3, 4, 5, 6]
[7, 0, 1, 2]
8
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40970290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档