21

Вопрос по list, python – Как найти общие элементы в списке списков?

Я пытаюсь понять, как сравнить n списков, чтобы найти общие элементы. Например:

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

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

Теперь, если я знаю количество элементов, я могу сделать сравнение, например:

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

но это не сработает, если я не знаю, сколько элементов p имеет. Я рассмотрел это решение, в котором сравниваются два списка. https://stackoverflow.com/a/1388864/1320800

но, потратив 4 часа, пытаясь придумать способ сделать это рекурсивным, решение все равно ускользает от меня, поэтому любая помощь будет высоко оценена!

  • @ user1320800: первая версия этого ответа была неправильнойprint заявление в конце. Конечно, мы должны напечататьresultнеs.

    от
  • Спасибо за ответ ... Я ничего не знал о наборах, поэтому я собираюсь исследовать еще немного. Однако из предварительного теста p = [[1,2,3], [1,3], [8,1]] решение, которое вы предложили вместо [1], возвращает [8,1]?

    от 8bits
  • Спасибо за помощь! это прекрасно работает, и теперь я знаю, что такое наборы :)

    от 8bits
  • +1 за использование наборов, где наборы являются подходящим типом данных.

    от
  • С другой стороны,result &= s.

    от
  • Также,zip удалит элементы, если длина списков будет разной.

    от
  • Мой код работает, только если мы смотрим на все общие элементы, которые также находятся в той же позиции; в этом вся суть zip (* p). Это то, что, как я думал, хотел ОП, но, читая пост снова, я, вероятно, неправильно понял. Я также предположил, что каждый подсписок имеет одинаковую длину.

    от
  • @ 8bit: Пожалуйста, смотрите мое редактирование.

    от
  • точно, подписчики не всегда одинаковой длины, тем не менее, спасибо за помощь!

    от 8bits
  • Я не знаю, пропустил ли я что-то, но передача p = [[1,2,3], [1,9,9], [1,2,4]], похоже, не сработала

    от 8bits
  • Попробуйте это с p = [[1,2], [2,1]]. Или даже р = [[1,2], [2]].

    от
  • @agf: Понятно. Тем не менее, это рабочее решение (хотя и немного неэффективное).

    от
  • reduce не считается "Pythonic" по многим. Кроме того, ваша версия требует, чтобы каждый список был преобразован в набор и для каждого пересечения должен быть создан дополнительный новый набор. Версия Свена создает только один набор.

    от
  • Я не знал, что правильным термином было «пересечение». так что спасибо за это. Это поможет мне разобраться в этом подробнее. Теперь он не должен быть рекурсивным, но мы только что узнали о рекурсии, поэтому я решил, что, вероятно, мне придется сравнить p [0] и p [1], а затем передать результат остальным элементам, то есть почему я подумал, что, вероятно, это будет рекурсивное решение

    от 8bits
  • Ваше решение должно быть рекурсивным? Можете ли вы использовать встроенныйintersect функции (то есть это домашнее задание?)?

    от K Mehta
  • возможный дубликатPython: How to find list intersection?

    от Daniel A. White
7 ответов
  • 15

    Code:

    >>> p=[ [1,2,3],
        [1,9,9],
        [1,2,4]]
    >>> set(p[0]).intersection(*p)
    set([1])
    

  • 1

    Code:

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

  • 1

    Результат: >>> ans [1]

    p=[ [1,2,3],
        [1,9,9],
        [1,2,4]]
    
    ans = [ele[0] for ele in zip(*p) if len(set(ele)) == 1]
    

    Результат:

    >>> ans
    [1]
    

  • 5

    Почему бы просто: set.intersection(*map(set, p))

    Почему бы просто:

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

    Результат:

    set([1])
    

    Или вот так:

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

    Результат:

    set([1])
    

    редактировать:

    скопировано с консоли:

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

  • 5

    Простое решение (в одну строку):

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

  • 42

    Вы ищете пересечение множеств всех подсписков

    и тип данных, который вы должны использовать для операций над множествами, является множеством:

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

  • 0

    Вы ищете пересечение множеств всех подсписков

    и тип данных, который вы должны использовать для операций над множествами, является множеством:

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

    Однако существует ограничение в 10 списков в списке. Все, что больше, вызывает «результат» список будет не в порядке. Предполагая, что вы "сделали" результат " в списокlist(result).

    Убедись, что тыresult.sort() чтобы убедиться, что он заказан, если вы зависите от этого.