Удалить кортеж из списка кортежей, если элементы кортежа отсутствуют в списке строк - PullRequest
0 голосов
/ 17 июня 2019

Я работаю над кодом, в котором мне нужно удалить кортеж из списка кортежей, если кортеж не содержит все строки в отдельном списке. У меня это работает в цикле for, но я пытаюсь повысить эффективность своего кода. Как пример, если у меня есть

list_of_tups = [('R', 'S', 'T'), ('A', 'B'), ('L', 'N', 'E'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
needed_strings = ['R', 'S', 'T']

Я хочу оставить в своем списке следующие кортежи:

[('R', 'S', 'T'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]

Это работает в следующем цикле for:

for s in needed_strings:
    for tup in list_of_tups:
        if s not in tup:
            list_of_tups.remove(tup)

Однако я бы хотел, чтобы это было сделано через понимание списка. Мои попытки сделать это приводят к появлению списка кортежей, в котором any строк, а не all , появляются в кортеже.

Ответы [ 4 ]

5 голосов
/ 17 июня 2019

Вы можете использовать all с вложенным пониманием:

list_of_tups = [('R', 'S', 'T'), ('A', 'B'), ('L', 'N', 'E'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
needed_strings = ['R', 'S', 'T']

[t for t in list_of_tups if all(c in t for c in needed_strings)]

результат

[('R', 'S', 'T'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]

До тех пор, пока списки содержат хешируемые элементы, альтернатива, которая может быть немного проще для чтения, - сделать needed_strings a set. Тогда вы можете использовать issubset()

list_of_tups = [('R', 'S', 'T'), ('A', 'B'), ('L', 'N', 'E'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
needed_strings = set(['R', 'S', 'T'])

[t for t in list_of_tups if needed_strings.issubset(t)]
1 голос
/ 17 июня 2019
list_of_tups = [
    ('R', 'S', 'T'), 
    ('A', 'B'), 
    ('L', 'N', 'E'), 
    ('R', 'S', 'T', 'L'), 
    ('R', 'S', 'T', 'L', 'N', 'E')
]
needed_chars = {'R', 'S', 'T'}  # using a set to speed up membership operations

# Append the tuple element from the list of tuples if the condition is met
list_of_tups_removed = [
    tup
    for tup in list_of_tups
    if any(c in needed_chars for c in tup)  # if any of the characters are present in needed_chars 
]

print(list_of_tups_removed)

Выход:

[('R', 'S', 'T'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]

Синтаксис понимания списка может использоваться только для создания нового списка. Его нельзя использовать для удаления элементов из существующего списка.

1 голос
/ 17 июня 2019

Вы можете попробовать это,

list_of_tups = [('R', 'S', 'T'), ('A', 'B'), ('L', 'N', 'E'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
needed_strings =['R', 'S', 'T']
y=[x for x in list_of_tups if set(needed_strings).issubset(set(x))] 
print(y)

Выход:

[('R', 'S', 'T'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
0 голосов
/ 17 июня 2019

Вы также можете использовать функцию lambda и set.issubset, чтобы проверить, есть ли каждый элемент в needed_strings в данном элементе списка list_of_tups и, наконец, отфильтровать его:

list_of_tups = [('R', 'S', 'T'), ('A', 'B'), ('L', 'N', 'E'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
needed_strings = ['R', 'S', 'T']
print(list(filter(lambda x: set(tuple(needed_strings)).issubset(x), list_of_tups)))

output:

[('R', 'S', 'T'), ('R', 'S', 'T', 'L'), ('R', 'S', 'T', 'L', 'N', 'E')]
...