Как удалить список списков на основе заданного списка кортежей? - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть два списка, как показано ниже.

l=[['A', 'B', 'C'], ['A', 'C'], ['A', 'B', 'C'], ['A', 'B'],['B','C']]
x=[('A', 'B'), ('A', 'C')]

Я хочу удалить список из l, которого нет в списке кортежей в x.

, например l ['B','c'] список присутствует, но у нас нет (B,C) комбинации в x, поэтому нам нужно удалить, т.е. B, C оба элемента не представили ни одного кортежа в X. Мой ожидаемый результат будет:

[['A', 'B', 'C'], ['A', 'C'], ['A', 'B', 'C'], ['A', 'B']

Ответы [ 4 ]

0 голосов
/ 07 декабря 2018

Хотя все вышеперечисленное работает, Один значительно быстрее.Ниже приводится измеренное время в секундах каждого решения для 100 000 прогонов.

  • schwobaseggl: 0.80720812
  • long_for_loop: 0.7031608010000001
  • shlomiLan 0.24393211999999997

Как видно выше, shlomiLan почти в 3 раза быстрее любого другого решения.код, используемый для получения результатов, можно увидеть здесь:

import timeit
setup = """
l = [['A', 'B', 'C'], ['A', 'C'], ['A', 'B', 'C'], ['A', 'B'],['B','C']]
x = [('A', 'B'), ('A', 'C')]"""

schwobaseggl = "[l_ for l_ in l if any(all(e in l_ for e in x_) for x_ in x)]"

long_for_loop = '''
c = []
for l_ in l:
    d = []
    for x_ in x:
        a = []
        for e in x_:
            if e in l_:
                a.append(True)
            else:
                a.append(False)
                break
        if all(a):
            d.append(True)
    if any(d):
        c.append(l_)
'''

shlomiLan = """new_list = []
for i in l:
    # Must use a flag, because we have 2 items that are the same in l (['A', 'B', 'C'])
    # so can't use append if i not new_list
    is_i_added = False
    for z in x:
        if is_i_added:
            continue

        j_not_in_i = False
        for j in z:
            if j not in i:
                j_not_in_i = True

        if not j_not_in_i:
            new_list.append(i)
            is_i_added = True"""

miklos_Horvath = "l = list(filter(lambda m: any(all(e in m for e in y) for y in x), l))"

a = timeit.timeit(setup=setup, stmt=schwobaseggl, number=100000)
b = timeit.timeit(setup=setup, stmt=long_for_loop, number=100000)
c = timeit.timeit(setup=setup, stmt=shlomiLan, number=100000)
d = timeit.timeit(setup=setup, stmt=miklos_Horvath, number=100000)
0 голосов
/ 07 декабря 2018

Используйте такой фильтр:

l=[['A', 'B', 'C'], ['A', 'C'], ['A', 'B', 'C'], ['A', 'B'],['B','C']]
x=[('A', 'B'), ('A', 'C')]

l = list(filter(lambda m: any(all(e in m for e in y) for y in x), l))

print(l)
0 голосов
/ 07 декабря 2018

Для меня это сложно для однострочника.

new_list = []
for i in l:
    # Must use a flag, because we have 2 items that are the same in l (['A', 'B', 'C'])
    # so can't use append if i not new_list
    is_i_added = False
    for z in x:
        if is_i_added:
            continue

        j_not_in_i = False
        for j in z:
            if j not in i:
                j_not_in_i = True

        if not j_not_in_i:
            new_list.append(i)
            is_i_added = True

print(new_list)
0 голосов
/ 07 декабря 2018

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

>>> [l_ for l_ in l if any(all(e in l_ for e in x_) for x_ in x)]
[['A', 'B', 'C'], ['A', 'C'], ['A', 'B', 'C'], ['A', 'B']]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...