3

I have a dict, of varying length. Each entry has a name and a list as so:

somedict = {'Name': [1, 2, 3], 'Name2': [], 'Name3': [2,3] }

How do I get the intersection for the following list? I need to do it dynamically, I don't know how long the dict will be.

For the above list, the intersection would be empty, I know. But for

somedict = {'Name': [1, 2, 3], 'Name3': [2,3] }

It should return

[2, 3]
thefourtheye
  • 221,210
  • 51
  • 432
  • 478
enrm
  • 568
  • 1
  • 7
  • 21

2 Answers2

11

Normally, intersection is a set operation. So, you might want to convert the values of the dictionary to sets and then run intersection, like this

>>> set.intersection(*(set(values) for values in data.values()))
{2, 3}

If you want the result to be a list, just convert the resulting set to a list, like this

>>> list(set.intersection(*(set(values) for values in data.values())))
[2, 3]

Here, the expression, *(set(values) for values in data.values()) creates a generator, which yields each and every value of the dictionary item converted to a set and the generator is unpacked to the set.intersection function.

Community
  • 1
  • 1
thefourtheye
  • 221,210
  • 51
  • 432
  • 478
1

Provide another way using reduce.

reduce(lambda x,y: set(x) & set(y), the_list)

the way it behave is like(e.g the_list = [[1, 2, 3], [], [2,3]]):

set([1,2,3]) & set([]) => tmp_result
set(tmp_result) & set([2,3]) => final_result

so the solution will be:

>>> dict_one = {'Name': [1, 2, 3], 'Name2': [], 'Name3': [2, 3]}
>>> reduce(lambda x,y: set(x) & set(y), dict_one.values())
set([])
>>> dict_two = {'Name': [1, 2, 3], 'Name3': [2, 3]}
set([2, 3])
>>> list(dict_two)
[2, 3]
lord63. j
  • 4,220
  • 2
  • 19
  • 29