Python:在for循环中

值得称赞的

问题:

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从清单中删除
  • #2使用列表理解功能创建新列表
  • #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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章