从子列表列表中删除所有相同名称的项目

时间:2014-07-01 22:14:45

标签: python list python-2.7 recursion

我正在尝试从包含子列表的列表中删除某个字符串的所有实例。例如,像这样:

myarray = ['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]

像这样结束

mylist = [['b'],['c','d'],['d']]
删除'a'的所有实例后

我使用过这段代码:

def delnodata(lst, what):
for index, item in enumerate(lst):
    if type(item) == list:
        delnodata(item, what)
    else:
        if item == what:
            lst.remove(item)
delnodata(mylist, 'a')

但输出是:

[['b', 'a'], ['c', 'd'], 'a', ['a', 'd']]

我在这个网站上看到了很多类似的问题,但遗憾的是我的编程技巧还不足以让我自己把它们整合在一起!

4 个答案:

答案 0 :(得分:4)

我会递归地这样做。这也适用于任意嵌套级别。

myarray = ['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]

def nestremove(lst, what):
    new = []
    for item in lst:
        if isinstance(item,list):
            new.append(nestremove(item,what))
        elif item != what:
            new.append(item)
    return new

print(myarray)
myarray = nestremove(myarray, 'a')
print(myarray)

该函数返回一个新列表,因此我们不必在迭代它时从原始列表中删除项目,正如其他人已经指出的那样可能很危险(请参阅this问题,尤其是注释)。相反,您可以重新分配myarray

输出:

['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]
[['b'], ['c', 'd'], ['d']]

答案 1 :(得分:3)

首次使用for index, item in enumerate(lst[:]),因此它会循环显示lstdelnodata(myarray, 'a')而不是delnodata(mylist, 'a')的完整副本,因为您已将其放入

myarray = ['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]
def delnodata(lst, what):
    for index, item in enumerate(lst[:]):
        if type(item) == list: # This if statement is optional
            delnodata(item, what)
        else:
            if item == what:
                lst.remove(item)
    print lst

delnodata(myarray, 'a')

答案 2 :(得分:2)

以下代码返回一个新列表,删除了'a'。它不会修改列表,这可能会导致神秘的问题。

myarray = ['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]

def testme(data):
    for item in data:
        if type(item) is list:
            yield list( testme(item) )
        elif item != 'a':
            yield item

res = list( testme(myarray) )
print res
assert res==[['b'],['c','d'],['d']], res

输出

[['b'], ['c', 'd'], ['d']]

答案 3 :(得分:2)

从列表中一次删除一个项目是非常低效的,因为每次都需要移动以下项目来填充空间。您应该只创建一个新的过滤列表

>>> def remover(data, r):
...     return [remover(x, r) if isinstance(x, list) else x for x in data if x != r]
... 
>>> myarray = ['a', 'a', ['b', 'a', 'a'], ['a', 'c', 'd', 'a'], 'a', ['a', 'd']]
>>> remover(myarray, 'a')
[['b'], ['c', 'd'], ['d']]