Есть ли способ сократить несколько вложенных циклов и циклов if в python, который заканчивается списком, удаляющим или добавляющим элемент? - PullRequest
2 голосов
/ 02 марта 2020

У меня есть следующая функция, которая берет число из списка в списке в списке (странная настройка, но это необходимо для остальной части операции на моем конце), которая сортирует все списки и удаляет число из самый внутренний список. У меня есть несколько функций, которые также добавляются, и я написал их таким образом с несколькими вложенными циклами for и if.

list = [['John', ['1','2','3']], ['Bob', ['4','5','6','7']], ['Jim', ['8','9']]]
def removeNumber(Number):
    for x in list:
        for y in x[1]:
            if y == Number:
                x[1].remove(Number)
removeNumber('5')
print(list)

Вышеприведенный блок кода работает, так как в нем удаляется указанное число из самого внутреннего списка, но я думаю, что мы все можем согласиться, что это выглядит ужасно с таким количеством вложенных циклов и if. Я довольно новичок в python и не очень хорошо разбираюсь в списках.

Мне интересно, есть ли способ написать это, используя понимание списка, или есть ли лучший способ вообще использовать другой метод. Лучшее значение вписывается в мантру «квартира лучше, чем вложенная». Любая помощь по этому вопросу будет высоко ценится

Ответы [ 4 ]

2 голосов
/ 02 марта 2020

У вас есть ошибка в этом коде. Удаление элемента в x[1] приводит к тому, что внешний for пропускает элементы в списке. Если вы хотите сохранить исходный список, выполните

def removeNumber(Number):
    for x in list:
        while Number in x[1]:
            x[1].remove(Number)

Но в python мы обычно просто создаем новые списки

def removeNumber(Number):
    for x in list:
        x[1] = [n for n in x[1] if n != Number]
2 голосов
/ 02 марта 2020

Вот возможное решение, я сделал его несколько многословным, чтобы упростить его понимание:

names = [['John', ['1','2','3']], ['Bob', ['4','5','6','7']], ['Jim', ['8','9']]]

def remove_number(number_to_remove):
    for item in names:
        new_values = [value for value in item[1] if value != number_to_remove]
        item[1] = new_values

remove_number('5')
print(names)

Я взял на себя свободу делать переменные и имя функции более Pythoni c.

Это также поможет устранить несколько ошибок, как указано в комментариях от 0x5453 :

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

Кроме того, обычно это ошибка удаления элементов из контейнера, по которому вы сейчас выполняете итерацию. (Например, попробуйте ваш пример с ['Bob', ['4', '5', '5', '5', '6', '7']] и посмотрите, что произойдет.)

0 голосов
/ 03 марта 2020

вы можете использовать списки для фильтрации Number:

def removeNumber(Number):
    return [[n, [e for e in l if e != Number]] for n, l in names]

names = removeNumber('5')
0 голосов
/ 03 марта 2020

Не уверен, имеет ли это смысл, но вы можете использовать рекурсию, чтобы уменьшить количество вложенных циклов:

input_list = [['John', ['1','2','3']], ['Bob', ['4','5','6','7']], ['Jim', ['8','9']]]

def removeNumber2(Number, _list):
    for x in _list:
        if Number in _list:
            _list.remove(Number)
        elif type(x) is list:
            removeNumber2(Number,  x)

removeNumber2('5', input_list)
print(input_list)

Та же идея, более чистый код, но, очевидно, работает медленно:

def removeNumber3(Number, _list):
    for x in _list:
        try:
            _list.remove(Number)
        except:
            removeNumber2(Number,  x)

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