2012-04-08 28 views
16

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

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

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

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

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

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

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

+0

Возможный дубликат [Python: Как найти список пересечений?] (Http://stackoverflow.com/questions/3697432/python-how-to-find-list-intersection) –

+0

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

+0

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

ответ

33

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

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

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

+0

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

+0

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

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

'сокращение' не считается« Pythonic »многими. Также ваша версия требует, чтобы каждый список был преобразован в набор, а также новый новый набор созданный для каждого пересечения. Версия Sven создает только один набор. – agf

+0

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

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] 
+1

Попробуйте это с помощью p = [[1,2], [2,1 ]] Или даже p = [[1,2], [2]]. – DSM

+0

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

+0

Кроме того, 'zip' будет отбрасывать элементы, если списки различаются по длине. –

4

Почему не просто:

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

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

+0

@ 8bits: см. Мое редактирование. – pillmuncher

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

Простое решение (одна линия) является:

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

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

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

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

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

Смежные вопросы