在中使用for的python字符串迭代的时间复杂性

在中使用for的python字符串迭代的时间复杂性,python,string,loops,iterator,time-complexity,Python,String,Loops,Iterator,Time Complexity,Python在使用字符串进行迭代构造时的时间复杂度是多少 例如: 循环的总运行时间是多少 编辑:我发现我把Python的字符串切片查找和字符串迭代混淆了。它的索引查找是O1,它在O1处迭代,因此total循环应该是打开的,与列表相同。On是答案。 查看此网站以了解有关时间复杂性的更多信息 答案就在上面。 查看此网站以了解有关时间复杂性的更多信息 它是打开的,但是索引查找参数是一个麻烦 迭代的工作原理 如果您这样做,索引查找速度将很重要: for index in range(len(mystri

Python在使用字符串进行迭代构造时的时间复杂度是多少

例如:

循环的总运行时间是多少

编辑:我发现我把Python的字符串切片查找和字符串迭代混淆了。它的索引查找是O1,它在O1处迭代,因此total循环应该是打开的,与列表相同。

On是答案。 查看此网站以了解有关时间复杂性的更多信息 答案就在上面。 查看此网站以了解有关时间复杂性的更多信息

它是打开的,但是索引查找参数是一个麻烦

迭代的工作原理 如果您这样做,索引查找速度将很重要:

for index in range(len(mystring)):
    char = mystring[index]
    ...
但你没有使用索引。您使用的是迭代器,更准确地说是字符串迭代器:

>>> iter('test')
<str_iterator object at 0x03569820>
这样做:

it = iter('test')
while True:
    try:
        char = next(it)
    except StopIteration:
        break
    print(char)
打印出这个:

t
e
s
t
字符串迭代的返回时间复杂性 让我们看看源代码。我对它不是非常熟悉,但我会描述我的信仰。记得这是一个str_迭代器吗?Python3中的str在Python2中称为unicode,这仍然是Python3的C源代码中的名称。在中我们找到字符串str_迭代器,它位于Unicode迭代器部分。摘录:

/********************* Unicode Iterator **************************/

typedef struct {
    ...
    Py_ssize_t it_index;
    PyObject *it_seq;    /* Set to NULL when iterator is exhausted */
} unicodeiterobject;
...
unicodeiter_next(unicodeiterobject *it)
{
    ...
    seq = it->it_seq;
      ...
        void *data = PyUnicode_DATA(seq);
        Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index);
        item = PyUnicode_FromOrdinal(chr);
        if (item != NULL)
            ++it->it_index;
        return item;
    ...
}
...
PyTypeObject PyUnicodeIter_Type = {
    ...
    "str_iterator",         /* tp_name */
   ...
};
所以它是一个unicodeiterobject,有一个指向它迭代的字符串的指针和一个索引。它的下一个函数使用它们来获取下一个字符,增加索引并返回字符。好的,迭代器确实在内部使用索引。但是,与使用unicode_getitem函数的Python索引相比,该索引处于更低、更直接的内部级别:

static PyObject *
unicode_getitem(PyObject *self, Py_ssize_t index)
{
    void *data;
    enum PyUnicode_Kind kind;
    Py_UCS4 ch;
    ...
    if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) {
        PyErr_SetString(PyExc_IndexError, "string index out of range");
        return NULL;
    }
    kind = PyUnicode_KIND(self);
    data = PyUnicode_DATA(self);
    ch = PyUnicode_READ(kind, data, index);
    return unicode_char(ch);
}
两者看起来很相似,最终都使用PyUnicode_READkind、数据和索引。我找不到那个,但它应该相当简单,而且是O1,使整个迭代继续进行


还有一件事:@NickParsons在上面指出的方法解决了Python使用可变大小多字节字符表示的问题,这可能使索引查找取代O1。即使是这样,它也只会影响unicode_getitem函数。不是str_迭代器迭代器。因为迭代器绝对不会使用简单的字符串索引,而是指向下一个字符的第一个字节的指针,这样它就可以在O1中读取和前进。因此,它的整个迭代仍将处于启用状态。

它处于启用状态,但索引查找参数是一个令人费解的问题

迭代的工作原理 如果您这样做,索引查找速度将很重要:

for index in range(len(mystring)):
    char = mystring[index]
    ...
但你没有使用索引。您使用的是迭代器,更准确地说是字符串迭代器:

>>> iter('test')
<str_iterator object at 0x03569820>
这样做:

it = iter('test')
while True:
    try:
        char = next(it)
    except StopIteration:
        break
    print(char)
打印出这个:

t
e
s
t
字符串迭代的返回时间复杂性 让我们看看源代码。我对它不是非常熟悉,但我会描述我的信仰。记得这是一个str_迭代器吗?Python3中的str在Python2中称为unicode,这仍然是Python3的C源代码中的名称。在中我们找到字符串str_迭代器,它位于Unicode迭代器部分。摘录:

/********************* Unicode Iterator **************************/

typedef struct {
    ...
    Py_ssize_t it_index;
    PyObject *it_seq;    /* Set to NULL when iterator is exhausted */
} unicodeiterobject;
...
unicodeiter_next(unicodeiterobject *it)
{
    ...
    seq = it->it_seq;
      ...
        void *data = PyUnicode_DATA(seq);
        Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index);
        item = PyUnicode_FromOrdinal(chr);
        if (item != NULL)
            ++it->it_index;
        return item;
    ...
}
...
PyTypeObject PyUnicodeIter_Type = {
    ...
    "str_iterator",         /* tp_name */
   ...
};
所以它是一个unicodeiterobject,有一个指向它迭代的字符串的指针和一个索引。它的下一个函数使用它们来获取下一个字符,增加索引并返回字符。好的,迭代器确实在内部使用索引。但是,与使用unicode_getitem函数的Python索引相比,该索引处于更低、更直接的内部级别:

static PyObject *
unicode_getitem(PyObject *self, Py_ssize_t index)
{
    void *data;
    enum PyUnicode_Kind kind;
    Py_UCS4 ch;
    ...
    if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) {
        PyErr_SetString(PyExc_IndexError, "string index out of range");
        return NULL;
    }
    kind = PyUnicode_KIND(self);
    data = PyUnicode_DATA(self);
    ch = PyUnicode_READ(kind, data, index);
    return unicode_char(ch);
}
两者看起来很相似,最终都使用PyUnicode_READkind、数据和索引。我找不到那个,但它应该相当简单,而且是O1,使整个迭代继续进行


还有一件事:@NickParsons在上面指出的方法解决了Python使用可变大小多字节字符表示的问题,这可能使索引查找取代O1。即使是这样,它也只会影响unicode_getitem函数。不是str_迭代器迭代器。因为迭代器绝对不会使用简单的字符串索引,而是指向下一个字符的第一个字节的指针,这样它就可以在O1中读取和前进。因此,它的整个迭代仍将处于打开状态。

字符串中单个索引的查找时间处于打开状态。我明白了,谢谢。然后循环开始。被Python字符串不变性弄糊涂了。@NickParsons你刚才是在评论那句话,还是你认为这与这个问题有关?我想不是。这不是索引循环。即使索引不是O1,例如Python使用了可变大小的字符或字符的链接列表,迭代器仍然可以在On中遍历字符串,因为它记住了字符串的位置。@HeapOverflow它更像是一个一般观察。我不是python专家,所以我不知道字符串的迭代器是如何实现的。但是,如果迭代器的下一个方法是使用一个索引来获取下一个值,并且索引循环开始,那么我会想象t.c位于^2。@NickParsons如果您对迭代器的实现感兴趣,请参阅后面我的答案的新部分
以降低字符串迭代的时间复杂性。摘要:它确实使用索引,但如果不是O1,我肯定迭代器会使用O1,因为它有保持其状态的优势。因此,整个迭代仍将继续。但是是的,如果索引查找开始,迭代器使用它,迭代将开始^2。尽管要做到这一点,Python实现者必须是完全的noobs:-字符串中单个索引的查找时间为On。我明白了,谢谢。然后循环开始。被Python字符串不变性弄糊涂了。@NickParsons你刚才是在评论那句话,还是你认为这与这个问题有关?我想不是。这不是索引循环。即使索引不是O1,例如Python使用了可变大小的字符或字符的链接列表,迭代器仍然可以在On中遍历字符串,因为它记住了字符串的位置。@HeapOverflow它更像是一个一般观察。我不是python专家,所以我不知道字符串的迭代器是如何实现的。但是,如果迭代器的下一个方法是使用索引来获取下一个值,并且索引循环开始,那么我会想象t.c在^2上。@NickParsons如果您对迭代器的实现感兴趣,请参阅我的答案的新章节返回字符串迭代的时间复杂性。摘要:它确实使用索引,但如果不是O1,我肯定迭代器会使用O1,因为它有保持其状态的优势。因此,整个迭代仍将继续。但是是的,如果索引查找开始,迭代器使用它,迭代将开始^2。尽管要做到这一点,Python实现者必须是完全的noob:-这实际上没有字符串迭代。。但@Nick Parsons的评论显示您的解决方案是正确的。实际上,这并没有字符串迭代。。但是@Nick Parsons的评论表明你的解决方案是正确的。希望我接受这个。有没有办法揭示字符串迭代器在引擎盖下的作用?今天我将尝试一些实验。@Learningstatsbyexample完成后,请参阅添加的“返回字符串迭代的时间复杂性”一节。太棒了。请随意对这个问题投赞成票。。这可能会被删除,您的响应将消失。这太有帮助了。真希望我能接受。有没有办法揭示字符串迭代器在引擎盖下的作用?今天我将尝试一些实验。@Learningstatsbyexample完成后,请参阅添加的“返回字符串迭代的时间复杂性”一节。太棒了。请随意对这个问题投赞成票。。这可能会被删除,您的响应将消失。这很有帮助。