Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find common elements in list of lists

Tags:

python

list

set

I have a list of lists of words called wordlist as follows:

[['dog', 'cat', 'sheep', 'rabbit', 'kiss', 'time'], ['cow', 'pig', 'bomb', 'cat', 'sheep', 'cake', 'boy', 'new']]

I want to find the common elements in all the sub-lists. Hence, my desired output of the above list should be:

['cat', 'sheep']

In order to achieve this, I created sets using the below code:

sets = set(tuple(row) for row in wordlist)

The set look like this:

{('cow', 'pig', 'bomb', 'cat', 'sheep', 'cake', 'boy', 'new'), ('dog', 'cat', 'sheep', 'rabbit', 'kiss', 'time')}

There can be any number of words per list, and there can be any number of lists. So I can end up with uneven sets of any number. I know I can compare two sets using the intersection methods, but how do I compare across multiple sets to return only the common items?

like image 985
FlameDra Avatar asked Jan 29 '17 20:01

FlameDra


2 Answers

You are using set incorrectly. You may use it like:

my_list = [['dog', 'cat', 'sheep', 'rabbit', 'kiss', 'time'], ['cow', 'pig', 'bomb', 'cat', 'sheep', 'cake', 'boy', 'new']]

# convert list of list to list of sets
my_sets = map(set, my_list)

# perform intersection on each set present in list
common_items = set.intersection(*my_sets)

This could be written in one line as:

common_items = set.intersection(*map(set, my_list))

The value hold by common_items will be:

{'sheep', 'cat'}

Here is the solution giving same result with the slightly performance efficient approach:

#                              v no need to type-cast sub-lists to `set` here
set(my_list[0]).intersection(*my_list[1:])

# OR,
# set(my_list[0]).intersection(*my_list)
# as intersection of set with itself returns the same set

Since set.intersection accepts all the iterables, there is no need to type-cast all the sub-lists to set.

like image 117
Moinuddin Quadri Avatar answered Nov 09 '22 23:11

Moinuddin Quadri


The easiest way is to use map() to convert the inputs to sets, and then use set.intersection to find their commonalities:

>>> data = [['dog', 'cat', 'sheep', 'rabbit', 'kiss', 'time'],
            ['cow', 'pig', 'bomb', 'cat', 'sheep', 'cake', 'boy', 'new']]
>>> set.intersection(*map(set, data))
{'sheep', 'cat'}
like image 43
Raymond Hettinger Avatar answered Nov 09 '22 22:11

Raymond Hettinger