Удалить подсписок из вложенного списка (поиск индекса подсписка) - PullRequest
0 голосов
/ 09 января 2019

У меня есть такой вложенный список:

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

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Как подсказывает @ coldspeed , использование набора для проверки существования букв обеспечивает оптимальный 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]]]

Примечание: Всегда лучше использовать встроенные функции для удобства, поскольку это избавляет вас от необходимости заново изобретать колесо и обычно приводит к более короткому и краткому коду.

0 голосов
/ 09 января 2019

Вы можете эффективно изменить 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 возвращает True, если какой-либо из первых элементов подсписков отсутствует в 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]]]
...