问题:
test1 = [1, 2, 3]
for i in range(len(test1)): #Want to do the below for every element in test1
print(test1[i])
if test1[i] % 2 == 0: #if the element meets certain conditions, it gets deleted
del test1[i]
#The thing in test1 gets deleted, but the range gets not updated,
#and i iterates nonetheless, so 1 element gets ignored,
#and in the end, I get "list index out of range"
(在实际的代码中,有更多的if语句,并且数组中的内容不是整数,而是类的对象?!,所以列表理解更多-meh ...)
我想出了这种方法:
test1 = [1, 2, 3]
i = 0
x = len(test1)
while i < x:
print(test1[i])
if test1[i] % 2 == 0:
del test1[i]
x -= 1
i -= 1
i += 1
但是正如您所看到的,这要长5行(对于每个del,我必须添加2行...),这很丑陋,而且很烦人。有没有更好的方法来做这样的事情?就像重做命令一样,它直接进入for循环,更新范围,并让您选择i或其他?
您是否尝试过使用reversed
该范围?
test1 = [1, 2, 3]
for i in reversed(range(len(test1))):
print(test1[i])
if test1[i] % 2 == 0:
del test1[i]
>>> 3
>>> 2
>>> 1
print(test1)
>>> [1, 3]
这样,当您删除一个元素时,数组将减少,但是由于您以相反的顺序浏览列表,因此仅影响已处理元素的索引。
阅读所有评论后,我决定运行一些基准测试。我创建了1000个元素的列表和10,000,000个元素的列表,并尝试了3种方法:
对于1,000个元素的列表来说,时间并不重要,但是对于10,000,000个元素的列表而言,从列表中删除几乎是不可能的(创建新列表需要几个小时而不是半秒钟)。
用1,000个元素进行测试
>>> Test 0, 11th element: 7e-06 seconds
>>> Test 0, second last element: 2e-06 seconds
>>> Test 1: 0.00017 seconds
>>> Test 2: 0.000103 seconds
>>> Test 3: 0.000234 seconds
用10,000,000元素进行测试
>>> Test 0, 11th element: 0.011888 seconds
>>> Test 0, second last element: 4e-06 seconds
>>> Test 1: Too long!!
>>> Test 2: 0.941158 seconds
>>> Test 3: 0.681262 seconds
关于这一点,我强烈建议您使用列表理解或常规的for循环创建一个新列表。
这是我的代码:
from datetime import datetime
from random import randint
# Create my test lists of 10 000 000 elements
test_0 = []
#nb_el = 10000000
nb_el = 1000
while (len(test_0) < nb_el):
test_0.append(randint(0, 100))
test_1 = test_0[:] # clone list1
test_2 = test_0[:] # clone list1
test_3 = test_0[:] # clone list1
# Test #0
# Remove the 11th element and second last element
d1 = datetime.now()
del test_0[10]
d2 = datetime.now()
print('Test 0, 11th element: ' +
str((d2-d1).microseconds / 1000000.0) + ' seconds')
d1 = datetime.now()
del test_0[nb_el-2]
d2 = datetime.now()
print('Test 0, second last element: '
+ str((d2-d1).microseconds / 1000000.0) + ' seconds')
# Test #1 | TOO SLOW TO BE RAN with 10 000 000 elements
# Delete every element where element is a multiple of 2
d1 = datetime.now()
for i in reversed(range(len(test_1))):
if test_1[i] % 2 == 0:
del test_1[i]
d2 = datetime.now()
print('Test 1: ' + str((d2-d1).microseconds / 1000000.0) + ' seconds')
# Test #2
# Create a new list with every element multiple of 2
# using list comprehension
d1 = datetime.now()
test_2_new = [x for x in test_2 if x % 2 == 0]
d2 = datetime.now()
print('Test 2: ' + str((d2-d1).microseconds / 1000000.0) + ' seconds')
# Test #3
# Create a new list with every element multiple of 2
# using for loop
d1 = datetime.now()
test_3_new = []
for i in range(len(test_3)):
if test_3[i] % 2 == 0:
test_3_new.append(test_3[i])
d2 = datetime.now()
print('Test 3: ' + str((d2-d1).microseconds / 1000000.0) + ' seconds')
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句