有没有一种方法可以缩短多个for和if循环嵌套,并以删除或附加项的列表结尾?

时间:2020-03-02 20:37:37

标签: python list for-loop

我有以下函数,该函数从列表中的列表中的列表中获取一个数字(奇怪的设置,但对我而言,这是其余操作所必需的),它对所有列表进行排序并从中删除一个数字最里面的列表。我还添加了一些函数,并以这种方式编写了它们,并附带了一些嵌套的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)

上面的代码块可以正常工作,因为它从最内层的列表中删除了给定的数字,但是我想我们都可以接受这么多嵌套的for循环和if看起来很糟糕。我是python的新手,没有太多关于列表理解的练习。

我想知道是否有一种方法可以使用列表理解来写,或者是否有更好的方法可以使用另一种方法。更好的含义是符合“扁平比嵌套更好”的口头禅。在这方面的任何帮助将不胜感激

4 个答案:

答案 0 :(得分:2)

这是一个可能的解决方案,为了简化理解,我将其做了一些详细说明:

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)

我可以自由地使变量和函数名称更像Pythonic。

这也将有助于解决一些错误,如 0x5453 的评论中所述:

请务必注意,您应避免将list用作变量 名称,因为它隐藏了内置列表类型,这可能会导致 难以调试的错误。

此外,从容器中移除物品通常是一个错误 目前正在迭代中。 (例如,尝试使用['Bob' ['4','5','5','5','6','7']],看看会发生什么。)

答案 1 :(得分:2)

您在该代码中有一个错误。删除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 :(得分:0)

不确定这是否有意义,但是您可以使用递归来减少嵌套循环的数量:

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)

答案 3 :(得分:0)

您可以使用列表推导过滤掉Number

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

names = removeNumber('5')