python enumerate ,range下标迭代list区别---------注意大坑
一般除了写法没什么差别;如果迭代可变对象,迭代过程有增删,那要小心了。
for i,v in enumerate(Li_d) , 下标 i会从0 逐渐+1 直到 i=当前的长度-1 ;for item in Li_d 也是会动态的往后迭代Li_d
如果长度发生变化,就会产生意想不到的结果。
for i in range(len(Li_d)) , 下标 i会从0 逐渐+1 直到 i=初始长度-1
-
eg1:中途判断,pop了一项,后面的项下标都会 -1,导致后面的操作就会都漏掉填补过来的下一项
In [114]: Li_d = [{str(x): x**2} for x in range(5)] ...: Li_d ...: Out[114]: [{'0': 0}, {'1': 1}, {'2': 4}, {'3': 9}, {'4': 16}]> In [115]: for i, x in enumerate(Li_d): ...: print i ,len(Li_d) ...: if '1' in x: ...: Li_d.pop(i) ...: else: ...: x['k'] = 5+i ...: ...: x['j'] = 0 ...: Li_d ...: 0 5 1 5 2 4 3 4 Out[115]: [{'0': 0, 'j': 0, 'k': 5}, {'2': 4}, {'3': 9, 'j': 0, 'k': 7}, {'4': 16, 'j': 0, 'k': 8}] In [116]:
-
eg2:尾部添加 append。后面的操作对 新加进来的 项 也会操作
In [117]: Li_d = [{str(x): x**2} for x in range(5)] ...: Li_d ...: Out[117]: [{'0': 0}, {'1': 1}, {'2': 4}, {'3': 9}, {'4': 16}] In [118]: for i, x in enumerate(Li_d): ...: print i ,len(Li_d) ...: if '1' in x: ...: Li_d.append({'0-*':0}) ...: else: ...: x['k'] = 5+i ...: x['j'] = 0 ...: ...: Li_d ...: 0 5 1 5 2 6 3 6 4 6 5 6 Out[118]: [{'0': 0, 'j': 0, 'k': 5}, {'1': 1, 'j': 0}, {'2': 4, 'j': 0, 'k': 7}, {'3': 9, 'j': 0, 'k': 8}, {'4': 16, 'j': 0, 'k': 9}, {'0-*': 0, 'j': 0, 'k': 10}]
-
eg3 头部插入,或者当前元素插入,会导致 重复无限判断
Li_d = [{str(x): x**2} for x in range(5)] print (Li_d) for i, x in enumerate(Li_d): print (i ,len(Li_d)) if '1' in x: Li_d.insert(i,{'0-*':0}) else: x['k'] = 5+i x['j'] = 0 Li_d ..................无限迭代,试试?
for i in range(len(Li_d)) 这样的写法,不会随着长度变化而往后迭代
-
#python2, python3也一样 python3 //range 默认惰性的 xrange In [3]: Li_d = [{str(x): x**2} for x in range(5)] ...: ...: print(Li_d) ...: for i in xrange(len(Li_d)): ...: print(i ,len(Li_d)) ...: x = Li_d[i] ...: if '1' in x: ...: Li_d.insert(0,{'0-*':0}) ...: else: ...: x['k'] = 5+i ...: x['j'] = 0 ...: ...: Li_d ...: [{'0': 0}, {'1': 1}, {'2': 4}, {'3': 9}, {'4': 16}] (0, 5) (1, 5) (2, 6) (3, 7) (4, 8) Out[3]: [{'0-*': 0}, {'0-*': 0}, {'0-*': 0}, {'0-*': 0}, {'0': 0, 'j': 0, 'k': 5}, {'1': 1, 'j': 0}, {'2': 4}, {'3': 9}, {'4': 16}] In [4]:
迭代过程中,如果有增删操作,最好不要和其他操作放在一起,以免结果不确定