有关for循环遍历list的小技巧和注意点及其原理

1.enumerate()函数

enumerate()能够将list中的元素和元素下标打包成一个(下标,元素值)这样的元组,类似于将数组的下标和元素值用zip()打包。这个函数能够让我们方便的在遍历list的时候同时保存list元素的值和下标。

li = ['aaa', 'bbb', 456, 7]
# 直接使用print(enumerate(li))无法直接查看其值,要先转换为list才可以
print(list(enumerate(li)))  
for index, i in enumerate(li):
    print(index, i)
'''
[(0, 'aaa'), (1, 'bbb'), (2, 456), (3, 7)]
0 aaa
1 bbb
2 456
3 7
'''

2.使用for i in list时,改变i的值无法改变list里元素的值。

li1 = [1, 2, 3, 4, 6]
for i in li1:
    i += 9
    print(i, end=' ')
print('\n' + str(li1))
# 10 11 12 13 15 
# [1, 2, 3, 4, 6]

从上述例子可以看出,i改变了,而li1中的元素并未改变。对于字符串同样如此。

使用上述的enumerate()函数能够很容易解释这一点。

li = ['aaa', 'bbb', 'ccc']
li1 = [1, 2, 3, 4, 6]
for index, i in enumerate(li1[:1]):
    print(id(i))
    print(id(li[index]))
# 1949511477552
# 1949513267888

可以看出,i的地址和列表中对应元素的地址是不同的,因此改变i并不能够改变list中元素的值。若想通过for遍历list改变其中的值,需要通过下标进行改变。

若要探究更深层次的原因,则需要研究一下for循环的工作原理。

for循环的工作原理:

1.在内部对可迭代对象调用__iter__()方法,获取可迭代对象(lst.__iter__())

2.再一次次的通过迭代器对象调用__next__()方法获取迭代结果。 (迭代器对象.__next__()拿到一个返回值,然后将值赋给i)

3.循环步骤2,直到抛出StopIteration异常,for循环会捕捉到异常然后结束循环。

用代码举个例子:

lst = [1, 2]
# 创建迭代器对象
it = iter(lst)
print(it)  # 
# 输出迭代器的下一个元素
print(next(it))  # 1
print(next(it))  # 2
print(next(it))  # StopIteration
# 此时捕捉到异常 退出for循环

你可能感兴趣的:(list,python)