neolee / pilot

进入编程世界的第一课
589 stars 842 forks source link

关于 2-c 数据与数据库中 删除列表元素的一个问题。 #1508

Closed xu-kai-xu closed 2 years ago

xu-kai-xu commented 2 years ago

示例代码中给出了找到手机号码不以101开头的用户并将其删除的操作示例。

users = []
users.append(User(1, 'neo', 'thereisnospoon', 'neo@matrix.net', '101-0101'))
users.append(User(2, 'trinity', 'iloveyouneo', 'trinity@matrix.net', '101-1010'))
users.append(User(3, 'morpheus', 'ibelieve', 'morpheus@matrix.net', '101-1111'))

for user in users:
    print(f'uid={user.uid}: name={user.name}, email={user.email}')

users.append(User(4, 'merovingian', 'iknoweverything', 'merovingian@matrix.net', '777-7777'))

for user in users:
    print(user.mobile)

print('')
# 找到手机号码不以 ‘101’ 开头的用户并将其删除
for user in users:
    if not user.mobile.startswith('101'):
        users.remove(user)

for user in users:
    print(user.mobile)

然后想试试删除号码以101开头的用户,发现没有删除干净:

users = []
users.append(User(1, 'neo', 'thereisnospoon', 'neo@matrix.net', '101-0101'))
users.append(User(2, 'trinity', 'iloveyouneo', 'trinity@matrix.net', '101-1010'))
users.append(User(3, 'morpheus', 'ibelieve', 'morpheus@matrix.net', '101-1111'))

for user in users:
    print(f'uid={user.uid}: name={user.name}, email={user.email}')

users.append(User(4, 'merovingian', 'iknoweverything', 'merovingian@matrix.net', '777-7777'))

for user in users:
    print(user.mobile)

print('')
# 找到手机号码以 ‘101’ 开头的用户并将其删除
for user in users:
    if user.mobile.startswith('101'):
        users.remove(user)

for user in users:
    print(user.mobile)

思考之后发现,从列表中遍历元素时,如果删掉了某一个元素,这个位置之后的所有元素的序号会自动减一,但是遍历的编号会继续增加。这样的结果是,该位置之后的第一个元素就跳过了被判断的环节,所以导致没有删除掉所有以101开头的用户。修改的想法是,当发现一个满足删除要求的元素时,将编号值减一,重新遍历该元素,用 while 循环实现。

users = []
users.append(User(1, 'neo', 'thereisnospoon', 'neo@matrix.net', '101-0101'))
users.append(User(2, 'trinity', 'iloveyouneo', 'trinity@matrix.net', '101-1010'))
users.append(User(3, 'morpheus', 'ibelieve', 'morpheus@matrix.net', '101-1111'))

for user in users:
    print(f'uid={user.uid}: name={user.name}, email={user.email}')

users.append(User(4, 'merovingian', 'iknoweverything', 'merovingian@matrix.net', '777-7777'))

for user in users:
    print(user.mobile)

print('')
# 找到手机号码以 ‘101’ 开头的用户并将其删除
i = 0
while i < len(users):
    try:
        if users[i].mobile.startswith('101'):
            users.remove(users[i])
            i -= 1
            user = users[i]
    except IndexError:
        break
    i += 1

for user in users:
    print(user.mobile)
neolee commented 2 years ago

非常棒!

pierrelzw commented 2 years ago

还有一种思路,可以从列表的尾部开始遍历:

for user in users[::-1]:
    #do something    
xu-kai-xu commented 2 years ago
print('')
# 找到手机号码以 ‘101’ 开头的用户并将其删除
for user in users:
    if user.mobile.startswith('101'):
        users.remove(user)

for user in users:
    print(user.mobile)

@pierrelzw 这个看起来更简单~,虽然我还不大理解。