Почему list.remove () не работает в этом цикле for? - PullRequest
1 голос
/ 26 апреля 2019

У меня есть список списков:

W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]

Из каждого списка в W я хочу удалить нулевые записи.

Я пробовал следующее:

for idx in range(len(W)):
    W[idx].remove(0)
print(W)

Но он всегда вернется

[[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]

Здесь ничего не изменилось. Мне известно о том, что я не могу изменить объект во время итерации по нему, однако, поскольку я итерирую не по W, а по len(W), я не понимаю, почему мой код не будет работать.

Что я делаю не так?

Ответы [ 7 ]

6 голосов
/ 26 апреля 2019

Как сказал avloss, удаление удаляет только первое вхождение. Сделать понимание списка.

for idx in range(len(W)):
    W[idx] = [i for i in W[idx] if i != 0]
print(W)

и, как предложил @meowgoesthedog, вы можете сделать общее понимание списка:

W = [lst[item for item in lst if item !=0] for lst in W]
2 голосов
/ 26 апреля 2019

Я бы сказал, что лучше использовать фильтр с лямбда-выражением, чтобы отфильтровать нулевые значения.

    for idx in range(len(W)):
        W[idx]=list((filter(lambda a: a != 0, W[idx])))
        print(W)

Это даст вам следующий вывод:

    [[5.0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
    [[5.0], [5.0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
    [[5.0], [5.0], [], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
    [[5.0], [5.0], [], [5.0], [5.0, 0, 0, 0]]
    [[5.0], [5.0], [], [5.0], [5.0]]
2 голосов
/ 26 апреля 2019

Вы можете использовать функцию понимания списка и фильтрации для удаления элементов, имеющих нулевое значение, в каждом подсписке W:

W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
nw = [list(filter(lambda a: a != 0, k)) for k in W]

ВЫХОД :

[[5.0], [5.0], [], [5.0], [5.0]]
2 голосов
/ 26 апреля 2019

, если вы хотите удалить все 0 элементы, вы можете просмотреть список пользователей и отфильтровать:

W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
for idx in range(len(W)):
    W[idx] = [i for i in W[idx] if i != 0]
print(W)

вывод выглядит так:

[[5.0], [5.0], [], [5.0], [5.0]]

1 голос
/ 26 апреля 2019

Достаточно простого понимания списка.

W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
li  = [ [j] for i in W for j in i if j!=0]
print(li)
#[[5.0], [5.0], [5.0], [5.0]]
0 голосов
/ 26 апреля 2019

Поскольку в каждом подсписке имеется более 1 нулей, мы должны использовать два цикла for, если вы хотите придерживаться решения на основе циклов.

In [75]: for lst in W:
    ...:     num_zeros = lst.count(0)
    ...:     for _ in range(num_zeros):
    ...:         lst.remove(0)


In [76]: W
Out[76]: [[5.0], [5.0], [], [5.0], [5.0]]

Теперь вашcode:

In [79]: for idx in range(len(W)):
    ...:     W[idx].remove(0)
    ...: print(W)

дает решение:

[[5.0, 0, 0, 0], [5.0, 0, 0], [0, 0], [5.0, 0, 0], [5.0, 0, 0]]

, которое, как мы видим, не соответствует 1 нулю из числа нулей во входном списке.Это потому, что remove(obj) удалит только первое вхождение объекта.

0 голосов
/ 26 апреля 2019

Это потому, что l.remove(0) означает удалить первое вхождение этого элемента .чтобы удалить элемент по индексу, вы можете использовать del

W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
for idx in range(len(W)):
    del W[idx][0]
print(W)

, это производит

[[0, 0, 0, 0], [0, 0, 0], [0, 0], [0, 0, 0], [0, 0, 0]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...