Это сложно. В принципе, идея - это неволю и повторный поворот, но с завихрением:
select t.id,
max(case when which = 'codeTaxe1' then val end) as codeTaxe1,
max(case when which = 'codeTaxe2' then val end) as codeTaxe2,
. . .
from t cross apply
(select v.*, row_number() over (order by (select null)) as seqnum
from (values (t.codeTaxe1, 'codeTaxe1'), (t.codeTaxe2, 'codeTaxe2'), . . .
) v(val, which)
where val is not null
) tt
group by t.id, seqnum;
Попробуйте отсортировать каждый вложенный массив в алфавитном порядке, а затем вызвать двоичный поиск по каждому вложенному массиву, чтобы найти соответствующие элементы, которые вы хотите удалить. Это должно ускорить процесс!
Два основных метода для ускорения вашего процесса:
1) Объект set
имеет (в основном) время линейного доступа при тестировании на включение, тогда как объект list
должен пройти через весь список, так что он зависит от размера списка (т. е. время теста включения растет пропорционально размеру списка)
2) Избегайте создания промежуточных коллекций, если можете, используя генераторы и понимания, когда это возможно что они лениво оцениваются
Вот пример, который использует оба подхода:
#!/usr/bin/env python3
text_list = [["hello", "how", "are", "you", "fine", "thank", "you"],
["good", "morning", "have", "great", "breakfast"],
["you", "are", "a", "student", "I", "am", "a", "teacher"],
["trump", "it", "is", "a", "fake", "news"],
["obama", "yes", "we", "can"]]
# use a set() for remove words because testing for inclusion is much faster than a long list
# removed two of your original bad words so I could make sure it passed some
remove_words = set(["hello", "breakfast", "obama"])
#make a generator, rather than a list, because why not?
result = (sentence for sentence in text_list if all(word not in remove_words for word in sentence))
for acceptable in result:
print(acceptable)