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

Remove sublist from nested list (finding index of the sublist)

我有一个这样的嵌套列表:

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

我如何删除包含非 A、B、L 字符串的子列表(不仅删除非 A、B、L 的列表,还删除整个子列表) 我如何找到无效项目所属的子列表的索引(在本例中为 1)(需要进一步任务的索引)

这是我试过的,它可以找到无效的项目,但我不知道要找到子列表的索引

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 

我想要的结果是这样的:

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

您可以使用反向删除成语有效地就地修改 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 如果任何子列表的第一个元素不在 keep.

中则为真

或者,您可以使用列表理解创建一个新列表:

[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]]]

正如 所建议的那样,使用集合来检查字母是否存在允许优化 O(1) 查找。

如果你不想使用任何内置函数,如any(),首先创建一个函数来检查每个子列表内部列表的第一个字母是否存在:

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

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

如果您愿意,也可以不用元组解包:

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

然后你可以重建一个新的列表,过滤掉不正确的列表:

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]]]

或作为列表理解:

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]]]

注意:为了方便起见,使用内置函数总是更好,因为它可以避免您不得不重新发明轮子,并且通常会导致更短、更简洁的代码。