Как найти общие элементы в списках питон

i have worked out a full solution for deep intersection

def common_items_dict(d1, d2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    result = {}
    if use_set_for_dict_key_commons:
        shared_keys=list(set(d1.keys()).intersection(d2.keys())) # faster, order not preserved
    else:
        shared_keys=common_items_list(d1.keys(), d2.keys(), use_set_for_list_commons=False)

    for k in  shared_keys:
        v1 = d1[k]
        v2 = d2[k]
        if isinstance(v1, dict) and isinstance(v2, dict):
            result_dict=common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
            if len(result_dict)>0 or append_empty:
                result[k] = result_dict 
        elif isinstance(v1, list) and isinstance(v2, list):
            result_list=common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
            if len(result_list)>0 or append_empty:
                result[k] = result_list 
        elif v1 == v2:
            result[k] = v1
    return result

def common_items_list(d1, d2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    if use_set_for_list_commons: 
        result_list= list(set(d2).intersection(d1)) # faster, order not preserved, support only simple data types in list values
        return result_list

    result = []
    for v1 in d1: 
        for v2 in d2:
            if isinstance(v1, dict) and isinstance(v2, dict):
                result_dict=common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
                if len(result_dict)>0 or append_empty:
                    result.append(result_dict)
            elif isinstance(v1, list) and isinstance(v2, list):
                result_list=common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
                if len(result_list)>0 or append_empty:
                    result.append(result_list)
            elif v1 == v2:
                result.append(v1)
    return result


def deep_commons(v1,v2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    """
    deep_commons
     returns intersection of items of dict and list combinations recursively

    this function is a starter function, 
    i.e. if you know that the initial input is always dict then you can use common_items_dict directly
    or if it is a list you can use common_items_list directly

    v1 - dict/list/simple_value
    v2 - dict/list/simple_value
    use_set_for_dict_key_commons - bool - using set is faster, dict key order is not preserved 
    use_set_for_list_commons - bool - using set is faster, list values order not preserved, support only simple data types in list values
    append_empty - bool - if there is a common key, but no common items in value of key , if True it keeps the key with an empty list of dict

    """

    if isinstance(v1, dict) and isinstance(v2, dict):
        return common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
    elif isinstance(v1, list) and isinstance(v2, list):
        return common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
    elif v1 == v2:
        return v1
    else:
        return None


needed_services={'group1':['item1','item2'],'group3':['item1','item2']}
needed_services2={'group1':['item1','item2'],'group3':['item1','item2']}

result=deep_commons(needed_services,needed_services2)

print(result)

I’m trying to figure out how to compare an n number of lists to find the common elements.
For example:

p=[ [1,2,3],
    [1,9,9],
      ..
      ..
    [1,2,4]

>> print common(p)
>> [1]

Now if I know the number of elements I can do comparions like:

for a in b:
  for c in d:
    for x in y:
...

but that wont work if I don’t know how many elements p has. I’ve looked at this solution that compares two lists
https://stackoverflow.com/a/1388864/1320800

but after spending 4 hrs trying to figure a way to make that recursive, a solution still eludes me so any help would be highly appreciated!

Community's user avatar

asked Apr 8, 2012 at 21:23

8bits's user avatar

3

You are looking for the set intersection of all the sublists, and the data type you should use for set operations is a set:

result = set(p[0])
for s in p[1:]:
    result.intersection_update(s)
print result

answered Apr 8, 2012 at 21:25

Sven Marnach's user avatar

Sven MarnachSven Marnach

566k117 gold badges932 silver badges832 bronze badges

6

A simple solution (one-line) is:

set.intersection(*[set(list) for list in p])

answered Jan 9, 2017 at 23:35

WindChimes's user avatar

WindChimesWindChimes

2,8953 gold badges25 silver badges26 bronze badges

The set.intersection() method supports intersecting multiple inputs at a time. Use argument unpacking to pull the sublists out of the outer list and pass them into set.intersection() as separate arguments:

>>> p=[ [1,2,3],
        [1,9,9],
        [1,2,4]]

>>> set(p[0]).intersection(*p)
set([1])

answered Apr 8, 2012 at 22:39

Raymond Hettinger's user avatar

Raymond HettingerRaymond Hettinger

214k62 gold badges378 silver badges481 bronze badges

1

Why not just:

set.intersection(*map(set, p))

Result:

set([1])

Or like this:

ip = iter(p)
s = set(next(ip))
s.intersection(*ip)

Result:

set([1])

edit:

copied from console:

>>> p = [[1,2,3], [1,9,9], [1,2,4]]
>>> set.intersection(*map(set, p))
set([1])
>>> ip = iter(p)
>>> s = set(next(ip))
>>> s.intersection(*ip)
set([1])

answered Apr 8, 2012 at 22:00

pillmuncher's user avatar

pillmuncherpillmuncher

10k2 gold badges34 silver badges33 bronze badges

1

p=[ [1,2,3],
    [1,9,9],
    [1,2,4]]

ans = [ele[0] for ele in zip(*p) if len(set(ele)) == 1]

Result:

>>> ans
[1]

answered Apr 8, 2012 at 21:39

Akavall's user avatar

AkavallAkavall

81.7k51 gold badges205 silver badges248 bronze badges

6

reduce(lambda x, y: x & y, (set(i) for i in p))

answered Apr 8, 2012 at 21:30

Joel Cornett's user avatar

Joel CornettJoel Cornett

24k9 gold badges64 silver badges87 bronze badges

2

You are looking for the set intersection of all the sublists, and the data type you should use for set operations is a set:

result = set(p[0])  
for s in p[1:]:
   result.intersection_update(s)
print result

However, there is a limitation of 10 lists in a list. Anything bigger causes ‘result’ list to be out of order. Assuming you’ve made ‘result’ into a list by list(result).

Make sure you result.sort() to ensure it’s ordered if you depend on it to be that way.

answered Aug 30, 2017 at 14:24

spearna's user avatar

Пересечение списков, совпадающие элементы двух списков

Решение задачи на языке программирования Python

В данной задаче речь идет о поиске элементов, которые присутствуют в обоих списках. При этом пересечение списков и поиск совпадающих (перекрывающихся) элементов двух списков будем считать несколько разными задачами.

Если даны два списка, в каждом из которых каждый элемент уникален, то задача решается просто, так как в результирующем списке не может быть повторяющихся значений. Например, даны списки:

[5, 4, 2, 'r', 'ee'] и [4, 'ww', 'ee', 3]

Областью их пересечения будет список [4, 'ee'].

Если же исходные списки выглядят так:

[5, 4, 2, 'r', 4, 'ee', 4] и [4, 'we', 'ee', 3, 4],

то списком их совпадающих элементов будет [4, 'ee', 4], в котором есть повторения значений, потому что в каждом из исходных списков определенное значение встречается не единожды.

Начнем с простого – поиска области пересечения. Cначала решим задачу “классическим” алгоритмом, не используя продвинутые возможностями языка Python: будем брать каждый элементы первого списка и последовательно сравнивать его со всеми значениями второго.

a = [5, [1, 2], 2, 'r', 4, 'ee']
b = [4, 'we', 'ee', 3, [1, 2]]
 
c = []
 
for i in a:
    for j in b:
        if i == j:
            c.append(i)
            break
 
print(c)

Результат выполнения программы:

Берется каждый элемент первого списка (внешний цикл for) и последовательно сравнивается с каждым элементом второго списка (вложенный цикл for). В случае совпадения значений элемент добавляется в третий список c. Команда break служит для выхода из внутреннего цикла, так как в случае совпадения дальнейший поиск при данном значении i бессмыслен.

Алгоритм можно упростить, заменив вложенный цикл на проверку вхождения элемента из списка a в список b с помощью оператора in:

a = [5, [1, 2], 2, 'r', 4, 'ee']
b = [4, 'we', 'ee', 3, [1, 2]]
 
c = []
 
for i in a:
    if i in b:
        c.append(i)
 
print(c)

Здесь выражение i in b при if по смыслу не такое как выражение i in a при for. В случае цикла оно означет извлечение очередного элемента из списка a для работы с ним в новой итерации цикла. Тогда как в случае if мы имеем дело с логическим выражением, в котором утверждается, что элемент i есть в списке b. Если это так, и логическое выражение возвращает истину, то выполняется вложенная в if инструкция, то есть элемент i добавляется в список c.

Принципиально другой способ решения задачи – это использование множеств. Подходит только для списков, которые не содержат вложенных списков и других изменяемых объектов, так как встроенная в Python функция set() в таких случаях выдает ошибку.

a = [5, 2, 'r', 4, 'ee']
b = [4, 1, 'we', 'ee', 'r']
 
c = list(set(a) & set(b))
 
print(c)

Результат:

Выражение list(set(a) & set(b)) выполняется следующим образом.

  1. Сначала из списка a получают множество с помощью команды set(a).
  2. Аналогично получают множество из b.
  3. С помощью операции пересечения множеств, которая обозначается знаком амперсанда &, получают третье множество, которое представляет собой область пересечения двух исходных множеств.
  4. Полученное таким образом третье множество преобразуют обратно в список с помощью встроенной в Python функции list().

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

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

В список пересечения попадают оба равных друг другу значения из первого списка. Это происходит потому, что когда цикл извлекает, в данном случае, вторую 4-ку из первого списка, выражение i in b также возвращает истину, как и при проверке первой 4-ки. Следовательно, выражение c.append(i) выполняется и для второй четверки.

Чтобы решить эту проблему, добавим дополнительное условие в заголовок инструкии if. Очередной значение i из списка a должно не только присутствовать в b, но его еще не должно быть в c. То есть это должно быть первое добавление такого значения в c:

a = [5,  2, 'r', 4, 'ee', 4]
b = [4, 'we', 'ee', 3]
 
c = []
 
for i in a:
    if i in b and i not in c:
        c.append(i)
 
print(c)

Результат:

Теперь усложним задачу. Пусть если в обоих списках есть по несколько одинаковых значений, они должны попадать в список совпадающих элементов в том количестве, в котором встречаются в списке, где их меньше. Или если в исходных списках их равное количетво, то такое же количество должно быть в третьем. Например, если в первом списке у нас три 4-ки, а во втором две, то в третьем списке должно быть две 4-ки. Если в обоих исходных по две 4-ки, то в третьем также будет две.

Алгоритмом решения такой задачи может быть следующий:

  1. В цикле будем перебирать элементы первого списка.
  2. Если на текущей итерации цикла взятого из первого списка значения нет в третьем списке, то только в этом случае следует выполнять все нижеследующие действия. В ином случае такое значение уже обрабатывалось ранее, и его повторная обработка приведет к добавлению лишних элементов в результирующий список.
  3. С помощью спискового метода count() посчитаем количество таких значений в первом и втором списке. Выберем минимальное из них.
  4. Добавим в третий список количество элементов с текущим значением, равное ранее определенному минимуму.
a = [5, 2, 4, 'r', 4, 'ee', 1, 1,  4]
b = [4, 1, 'we', 'ee', 'r', 4, 1, 1]
 
c = []
 
for item in a:
    if item not in c:
        a_item = a.count(item)
        b_item = b.count(item)
        min_count = min(a_item, b_item)
        # c += [item] * min_count
        for i in range(min_count):
            c.append(item)
 
print(c)

Результат:

Если значение встречается в одном списке, но не в другом, то метод count() другого вернет 0. Соответственно, функция min() вернет 0, а цикл с условием i in range(0) не выполнится ни разу. Поэтому, если значение встречается в одном списке, но его нет в другом, оно не добавляется в третий.

При добавлении значений в третий список вместо цикла for можно использовать объединение списков с помощью операции + и операцию повторения элементов с помощью *. В коде выше данный способ показан в комментарии.

Больше задач в PDF

В этом посте мы обсудим, как найти общие элементы из двух списков в Python.

1. Использование intersection() функция

Простое и довольно эффективное решение состоит в том, чтобы преобразовать первый список в набор, а затем вызвать intersection() функция. Он возвращает новый набор с элементами, общими для набора с другой итерацией.

if __name__ == ‘__main__’:

    first = [1, 2, 3, 5]

    second = [2, 4, 5, 7]

    common = set(first).intersection(second)

    print(common)        # {2, 5}

Скачать  Выполнить код

2. Использование побитового сравнения

Вы также можете использовать основанный на операторе аналог intersection(), который оказывается побитовым, и (&) оператор. Но для этого необходимо установить оба аргумента, как показано ниже:

if __name__ == ‘__main__’:

    first = [1, 2, 3, 5]

    second = [2, 4, 5, 7]

    common = set(first) & set(second)

    print(common)        # {2, 5}

Скачать  Выполнить код

3. Использование понимания списка

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

if __name__ == ‘__main__’:

    first = [1, 2, 3, 5]

    second = [2, 4, 5, 7]

    common = [x for x in first if x in second]

    print(common)        # {2, 5}

Скачать  Выполнить код

Вот и все, что нужно для поиска общих элементов из двух списков в Python.

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂

29.12.2019Python, Программы Python

Проблема нахождения общих элементов в списке из 2 списков является довольно распространенной проблемой и может быть легко решена, а также обсуждалась много раз. Но иногда нам требуется найти общие элементы из N списков. Давайте обсудим некоторые способы, которыми эта операция может быть выполнена.

Метод № 1: Использование reduce() + lambda + set()
Эта конкретная задача может быть достигнута в одну строку, используя комбинацию вышеуказанных функций. Функция уменьшения может использоваться для управления функцией «&» для всего списка. Функция set может использоваться для преобразования списка в набор для удаления повторов.

from functools import reduce

test_list = [[2, 3, 5, 8], [2, 6, 7, 3], [10, 9, 2, 3]]

print ("The original list is : " + str(test_list))

res = list(reduce(lambda i, j: i & j, (set(x) for x in test_list)))

print ("The common elements from N lists : " + str(res))

Выход:

The original list is : [[2, 3, 5, 8], [2, 6, 7, 3], [10, 9, 2, 3]]
The common elements from N lists : [2, 3]

Способ № 2: Использование map() + intersection()
Функция map может использоваться для преобразования каждого из списков в наборы, которыми нужно управлять для выполнения пересечения, используя функцию set.intersection. Это самый элегантный способ выполнить эту конкретную задачу.

test_list = [[2, 3, 5, 8], [2, 6, 7, 3], [10, 9, 2, 3]]

print ("The original list is : " + str(test_list))

res = list(set.intersection(*map(set, test_list)))

print ("The common elements from N lists : " + str(res))

Выход:

The original list is : [[2, 3, 5, 8], [2, 6, 7, 3], [10, 9, 2, 3]]
The common elements from N lists : [2, 3]

Рекомендуемые посты:

  • Python | Объединить список с общими элементами в списке списков
  • Программа Python для поиска общих элементов в трех списках с использованием наборов
  • Python | Распечатать все общие элементы двух списков
  • Python | Количество общих элементов в списках
  • Python | Сортировка списка списков с похожими элементами списка
  • Python | Максимальная сумма элементов списка в списке списков
  • Python | Получить положительные элементы из данного списка списков
  • Python | Преобразовать столбец в отдельные элементы списка списков
  • Python | Найти наиболее распространенный элемент в 2D-списке
  • Python | Найти наиболее распространенный элемент в каждом столбце в 2D-списке
  • intersection_update () в Python для поиска общих элементов в n массивах
  • Python | Найти минимум каждого индекса в списке списков
  • Python | Найти частоту заданного символа в каждой позиции в списке списков
  • Python | Найти общие элементы в трех отсортированных массивах по пересечению словаря
  • Python | Программа для подсчета количества списков в списке списков

Python | Найти общие элементы в списке списков

0.00 (0%) 0 votes

Добавить комментарий