Python中的递增迭代器(iter)
Incrementing iterator (iter) in Python
例如,我有以下字符串:
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
现在,给定任何迭代器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)
您可以使用内置的enumerate()
函数:
for index, element in enumerate(mystring):
print index
print element
您可以执行以下操作:
import itertools
s = "mystring"
s2 = ''.join(itertools.islice(s, 0, 3))
但实际上,与其试图直接翻译C++习语,你应该找到Python的方式来做任何你想做的事情,这可能最终会更简洁。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 在取消引用-*iter++之后对迭代器进行后递增.它是如何评估的
- Python中的递增迭代器(iter)