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
  • 233,700
  • 52
  • 457
  • 497
enrm
  • 645
  • 1
  • 8
  • 22

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
  • 233,700
  • 52
  • 457
  • 497
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,500
  • 2
  • 22
  • 30