python - Python中的递增迭代器(iter)

标签 python c++ string iterator

例如,我有以下字符串:

s = "string"

我正在尝试为这个字符串对象维护一个迭代器。

it = iter(s)

我知道我可以使用循环并使用 next 调用递增 it

for i in range(0, len(s)):
    print(next(it))

这将打印该字符串中的所有字符。

但我有几件事情是我希望迭代器完成的,就像我在 std::list 上使用 C++ 迭代器所做的那样。

1.) 返回迭代器当前指向的元素。

   // In C++, I would do,

   std::string str = "string";

   std::string::iterator it = str.begin();
   *it; // gets the value of element

2.) 获取迭代器所在元素的索引。

这样我就可以使用 Python 切片方法获取子字符串:

例如:

s = "string"
s[0:iter_index_in_integer]

在 C++ 中,我可以使用迭代器:

   std::string str = "string";
   std::string::iterator it = str.begin();
   std::string(it, it+3);

是否可以像这样在 Python 中递增迭代器?如果不是,那么我可以使用迭代器当前指向的元素的索引,我该怎么做?

最佳答案

Python 的内置不提供任何允许您获取迭代器的“当前元素”的东西。迭代器必须支持的唯一操作是next 以获取后续元素推进迭代。

然而,编写自己的实现其他操作的迭代器非常简单:

class AugmentedIterator(object):
    _sentinel = object()

    def __init__(self, iterator):
        self.iterator = iterator
        self.value = self._sentinel

    def __iter__(self):
        return self

    def __next__(self):
        if self.value is not self._sentinel:
            self.value, val = self._sentinel, self.value
            return val
        return next(self.iterator)

    def peek(self, default=_sentinel):
        if self.value is not self._sentinel:
            return self.value
        try:
            self.value = next(self.iterator)
        except StopIteration:
            if default is not self._sentinel:
                return default
            raise
        else:
            return self.value

现在,给定 any 迭代器it,您可以将其包装到 AugmentedIterator 中,并且您可以随时调用 peek() 检查当前元素。

请注意,没有 end() 这样的东西,因为迭代器很容易是无限的。了解迭代器是否没有更多元素的唯一方法是调用 next 并查看它是否引发 StopIteration

对于您的第二个请求,您可以使用 itertools.islice 获取迭代器的一部分。但是请注意,islice 执行 python 切片,这允许越界索引:

In [19]: list(islice('string', 0, 1000))
Out[19]: ['s', 't', 'r', 'i', 'n', 'g']

这里的索引 1000 因为它比字符串长度大,所以只表示:直到结束。这与切片一致:

In [20]: 'string'[:1000]
Out[20]: 'string'

在 C++ 中,如果字符串的长度为 6,您在尝试使用 it+1000 时会遇到错误。(不是 100% 确定,但由于指针是可迭代的,您肯定会遇到一些麻烦至少在某些情况下)。


一般来说 itertools包包含很多有用的功能(在文档的末尾有一些使用它们的食谱)。 Python 还提供了一些迭代器相关的函数如:

  • enumerate : 迭代元素并获取相关索引。
  • map/filter/reduce
  • iter(callable, sentinel) : 允许您在给定不带参数的函数的情况下获得迭代器:

    for chunk in iter(lambda: file_object.read(4096), ''):
        handle(chunk)
    

    相当于:

    while True:
        chunk = file_object.read(4096)
        if chunk == '':
            break
        handle(chunk)
    

关于python - Python中的递增迭代器(iter),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22994730/

相关文章:

python - 查找 3 维 numpy 数组的唯一值的索引

python - pandas 获得每个类别的最多 3 个分数行

python - 如何在for循环python中使用计数器

python - 使用 python 获取 vnet 的所有属性 |列表函数仅给出名称

c++ - 为 WH_MOUSE 设置 WindowsHookEx

c++ - 对 std::wstring 的 vector 进行排序实际上会重写原始字符串数据吗?

algorithm - 如何计算非二次幂字母表的 de Bruijn 序列?

c++ - 如何进行从 std::string_view 到 std::string 的转换

c - 如何在C中打印另一个函数使用的函数参数?

python - 如何使用正则表达式提取文本 block 而不将文本 block 分成几行