在Python中迭代和更新列表 [英] Iterating and Updating the list in python

查看:167
本文介绍了在Python中迭代和更新列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我无法理解为什么下面的代码在不确定的
循环中(当我不使用复制列表时)



  list = [Mohit,kumar,sffsfshfsd] 
列表中的w:
if len(w))> 5:
list.insert(0,w)
print(inside loop)

print(list)
pre>

上面的代码无限期地打印循环内

现在,的名单,我使用下面的副本清单工作正常。

  list = [mohit,kumar, sffffgssddf] 

for list [:]:
if len(w)> 5:
list.insert(0,w)
print(inside loop)

print(list)
pre>


现在我已经阅读了python文档,这是行为
i会得到,但我想了解背后的原因它。感谢
advance。



解决方案第一个for循环 for w in list 将使用迭代器(来自 iter(list))来检索并遍历列表中的每个项目。这个迭代器不会立即获取整个列表 - 它是 lazy ,这意味着它只需要从列表中获取一个项目。您可以在这里了解迭代协议,或迭代/生成器和懒惰在这里



循环索引0和1不做任何事情,因为它们的字符串长度小于6.但是,在索引2处,您可以将sffsfshfsd添加到列表。现在 list 已经增长了,索引3处有一些东西:sffsfshfsd。然后迭代继续,从下一个索引(3)中选取值,然后在起始处再次添加索引值,将索引为3的相同值移至索引4 ...循环永不结束。

在第二个循环 w in list [:] 中,创建整个列表的一个 copy =https://stackoverflow.com/questions/509211/explain-slice-notation>通过使用切片运算符)并遍历。您正在将项目添加到原始列表中,而不是副本,因此迭代器将不会触及已添加的项目。



PS:我试图搜索Python源代码(这是C)来证明列表迭代器实际上使用增量索引(如上所述)。我不太熟悉Python的源代码,但是这里是我在 cpython / listobject.c

迭代器创建,将起始索引设置为0

  2797 static PyObject * 
2798 list_iter(PyObject * seq)
2799 {
....
2806 it = PyObject_GC_New(listiterobject,& PyListIter_Type) ;
...
2809 it-> it_index = 0;
....
2813 return(PyObject *)it;
2814}

next 使用 it-> it_index 然后递增

  2831 static PyObject * 
2832 listiter_next(listiterobject * it)
2833 {
....
2844 item = PyList_GET_ITEM(seq,it-> it_index);
2845 ++ it-> it_index;
....
2847退货项目;
....
2853}

似乎对我来说合法吗? p>

I am not able to understand why the following code goes in indefinite loop(when i am not using the copy list)

list = ["Mohit","kumar","sffsfshfsd"]
for w in list:
    if(len(w)) > 5:
        list.insert(0,w)
    print("inside loop")

print(list)  

The Above code prints inside loop indefinitely.

Now if in place of the list, i use a copy list like below works fine.

list = ["mohit","kumar","sffffgssddf"]

for w in list[:]:
    if len(w) > 5:
        list.insert(0,w)
    print("inside loop")

print(list)  

Now i have read in the python documentation that this is the behavior i will get but i want to understand the reason behind it. Thanks in advance.

解决方案

The first for loop for w in list will use an iterator (from iter(list)) to retrieve and loop through each item in the list. This iterator does not fetch the entire list immediately - it is lazy, meaning it only gets one item at a time from the list, when it's needed. You can learn about the iteration protocol here, or iteration/generators and laziness here.

Looping through indexes 0 and 1 do nothing, as their string lengths are less than 6. At index 2, however, you add "sffsfshfsd" to the beginning of list. Now list has grown and there's something at index 3: "sffsfshfsd". Iteration then continues, picking the value from the next index (3), which gets added at the beginning again, moving the same value which was at index 3 to index 4... The cycle never ends.

In your second loop w in list[:] you create a copy of the entire list (by using a slice operator) and iterate through that. You're adding items to the original list, not the copy, so the iterator won't touch the items that you've added.

PS: I tried to search the Python source code (which is C) to prove that list iterators in fact use an incrementing index (as described above). I'm not well versed in reading Python's source code, but here's what I found in cpython/listobject.c:

Iterator creation, sets starting index to 0

2797 static PyObject *
2798 list_iter(PyObject *seq)
2799 {
....
2806     it = PyObject_GC_New(listiterobject, &PyListIter_Type);
....
2809     it->it_index = 0;
....
2813     return (PyObject *)it;
2814 }

next uses it->it_index from above and then increments it

2831 static PyObject *
2832 listiter_next(listiterobject *it)
2833 {
....
2844         item = PyList_GET_ITEM(seq, it->it_index);
2845         ++it->it_index;
....
2847         return item;
....
2853 }

Seems legit to me?

这篇关于在Python中迭代和更新列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆