简体   繁体   English

从嵌套列表中删除子列表(子列表的查找索引)

[英]Remove sublist from nested list (finding index of the sublist)

I have a nested list like this: 我有一个这样的嵌套列表:

lists = [[['L', 5], ['B', 20], ['A', 10]], 
        [['B', 200], ['J', 90]], 
        [['L', 5], ['L', 6]], 
        [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

How can I remove sublists that have string which is not A,B,L(remove the whole sublist not only the list that not A,B,L) How can I find the index of sublist that invalid items belong to (in this case is 1)(need the index for further task) 如何删除字符串不是A,B,L的子列表(删除整个子列表,不仅删除不是A,B,L的列表)如何找到无效项所属的子列表的索引(在这种情况下)是1)(需要下一个任务的索引)

This is what I have tried, it can find invalid item but I do not know to find index of the sublist 这是我尝试过的,它可以找到无效的项目,但是我不知道找到子列表的索引

for j in range (len(lists)):
    for i in range (len(lists[j])):
        if lists[j][i][0] != 'L' and lists[j][i][0] != 'A' and lists[j][i][0] != 'B':
            return False
return True 

I want the result to be like this: 我希望结果是这样的:

lists = [[['L', 5], ['B', 20], ['A', 10]],  
        [['L', 5], ['L', 6]], 
        [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

You can efficiently modify lists inplace using the reverse-delete idiom: 您可以使用反向删除惯用法有效地就地修改lists

keep = ('A', 'B', 'L')
for i in reversed(range(len(lists))):
    if any(l[0] not in keep for l in lists[i]):  
        del lists[i]

print(lists)
# [[['L', 5], ['B', 20], ['A', 10]],
#  [['L', 5], ['L', 6]],
#  [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

any returns True if any of the sublists' first element is not in keep . 如果子列表的第一个元素不在keep ,则any返回True。


Alternatively, you can create a new list with a list comprehension: 或者,您可以创建一个具有列表理解的新列表:

[l for l in lists if not any(l_[0] not in keep for l_ in l)]
# [[['L', 5], ['B', 20], ['A', 10]],
#  [['L', 5], ['L', 6]],
#  [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

As @coldspeed suggests, using a set to check if the letters exists allows optimal O(1) lookups. 正如@coldspeed所建议的那样,使用一组检查字母是否存在可以实现最佳的O(1)查找。

If you don't want to use any builtin functions like any() , first make a function that checks if the first letter of each sublists inner list exists: 如果您不想使用任何内置函数(例如any() ,请首先创建一个检查每个子列表内部列表的第一个字母是否存在的函数:

valid = {"A", "B", "L"}

def check_valid(sublst):
    for fst, *_ in sublst: 
        if fst not in valid:
            return False
    return True

Or without tuple unpacking if you prefer: 或者,如果您愿意,也可以不进行元组拆箱:

def check_valid(sublst):
    for lst in sublst:
        if lst[0] not in valid:
            return False
    return True

Then you can reconstruct a new list with the incorrect lists filtered out: 然后,您可以重构出一个新列表,并过滤掉不正确的列表:

result = []
for sublst in lists:
    if check_valid(sublst):
        result.append(sublst)

print(result)
# [[['L', 5], ['B', 20], ['A', 10]], [['L', 5], ['L', 6]], [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

Or as a list comprehension: 或作为列表理解:

result = [sublst for sublst in lists if check_valid(sublst)]
print(result)
# [[['L', 5], ['B', 20], ['A', 10]], [['L', 5], ['L', 6]], [['A', 10], ['L', 12], ['A', 11], ['A', 15]]]

Note: It is always better to use builtin functions for convenience, since it saves you having to reinvent the wheel and usually leads to shorter, more concise code. 注意:为了方便起见,最好使用内置函数,因为这样可以省去重新编写轮子的麻烦,并且通常可以使代码更短,更简洁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM