This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Last empty string not removed in a list
Type: behavior Stage: resolved
Components: Versions: Python 3.8
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: kumarmakala, steven.daprano
Priority: normal Keywords:

Created on 2021-02-07 02:16 by kumarmakala, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg386571 - (view) Author: Kumar Makala (kumarmakala) Date: 2021-02-07 02:16
# Last empty string not removed from the list

str_list = ["Emma", "Jon", "", "Kelly","Eric", "", "","KXN",""]
for item in str_list:
    if len(item) == 0:

['Emma', 'Jon', 'Kelly', 'Eric', 'KXN', '']
msg386572 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-02-07 03:00
This is not a language bug, it is a bug in your code: you are modifying the list as you iterate over it.

There are lots of ways to do that task correctly, perhaps the easiest is with a filter:

    str_list = list(filter(bool, str_list))

or a list comprehension:

    str_list = [s for s in str_list if s]

or by iterating over a copy of the list:

    for item in str_list[:]:  # use slice syntax to make a copy
msg386573 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-02-07 03:22
The problem here is that you are shortening the list as you walk along it, which means you skip items. You expected to visit:

    "Emma", "Jon", "", "Kelly","Eric", "", "", "KXN", ""

in that order, but after visiting Emma, Jon and the first empty string, you delete the first empty string, which pushes every item down one position:

    "Emma", "Jon", "Kelly","Eric", "", "", "KXN", ""

The next item is now Eric, not Kelly, because Kelly is in the position already visited. So the *string* Kelly gets skipped. After visiting Eric and the next empty string, everything gets pushed down another spot:

    "Emma", "Jon", "Kelly","Eric", "", "KXN", ""

which moves the second empty string into the position that was already visited. The next item is now KXN, then the final empty string, which then deletes the *first remaining* empty string:

    "Emma", "Jon", "Kelly","Eric", "KXN", ""

and now you have reached the end of the string and there is nothing more to do.

You can see for yourself the items which are visited:

    >>> for item in str_list:
    ...     print('item =', repr(item))
    ...     if len(item) == 0:
    ...         str_list.remove(item)
    item = 'Emma'
    item = 'Jon'
    item = ''
    item = 'Eric'
    item = ''
    item = 'KXN'
    item = ''

Here is perhaps a more clear way to see what you are doing wrong:

    >>> str_list = ['a', 'x', 'b', 'x', 'c', 'x', 'd', 'x', 'e', 'f']
    >>> for item in str_list:
    ...     print(item, ''.join(str_list))
    ...     if item == 'x':
    ...         str_list.remove(item)
    a axbxcxdxef
    x axbxcxdxef
    x abxcxdxef
    x abcxdxef
    x abcdxef
    f abcdef

Every time you delete an item, the list shrinks, everything moves down one position, and the next item gets skipped because it has been moved into the slot already looked at.
msg386574 - (view) Author: Kumar Makala (kumarmakala) Date: 2021-02-07 03:36
Thanks Steven!
Date User Action Args
2022-04-11 14:59:41adminsetgithub: 87316
2021-02-07 03:36:57kumarmakalasetmessages: + msg386574
2021-02-07 03:22:00steven.dapranosetmessages: + msg386573
2021-02-07 03:00:20steven.dapranosetstatus: open -> closed

nosy: + steven.daprano
messages: + msg386572

resolution: not a bug
stage: resolved
2021-02-07 02:16:14kumarmakalacreate