2

Suppose I have a dict like:

aDict[1] = '3,4,5,6,7,8'
aDict[5] = '5,6,7,8,9,10,11,12'
aDict[n] = '5,6,77,88'

The keys are arbitrary, and there could be any number of them. I want to consider every value in the dictionary.

I want to treat each string as comma-separated values, and find the intersection across the entire dictionary (the elements common to all dict values). So in this case the answer would be '5,6'. How can I do this?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
khany
  • 1,167
  • 15
  • 33

5 Answers5

4
from functools import reduce # if Python 3

reduce(lambda x, y: x.intersection(y), (set(x.split(',')) for x in aDict.values()))
DrTyrsa
  • 31,014
  • 7
  • 86
  • 86
  • ok now i'm getting error: TypeError: Type str doesn't support the buffer API. Any ideas? What if the is just 1 dict entry? What happens then? – khany Oct 14 '11 at 09:56
  • just as a guide the actual dict with 1 entry looks like:- {4: b'1,2,31,47,52,56'}. This is what is causing the error. – khany Oct 14 '11 at 10:01
  • @khany I haven't worked with Python 3, but I think [this](http://www.rmi.net/~lutz/strings30.html) will be helpful. BTW, if you are Python newbie and you don't have any special reasons for 3rd version, I highly recommend using Python 2, it is mainstream version today. – DrTyrsa Oct 14 '11 at 10:05
  • hmm I was using v3 to future proof my code but I am now looking into v2. – khany Oct 14 '11 at 10:18
3

First of all, you need to convert these to real lists.

l1 = '3,4,5,6,7,8'.split(',')

Then you can use sets to do the intersection.

result = set(l1) & set(l2) & set(l3)
madjar
  • 12,691
  • 2
  • 44
  • 52
1

Python Sets are ideal for that task. Consider the following (pseudo code):

intersections = None
for value in aDict.values():
    temp = set([int(num) for num in value.split(",")])
    if intersections is None:
        intersections = temp
    else:
        intersections = intersections.intersection(temp)

print intersections
Constantinius
  • 34,183
  • 8
  • 77
  • 85
0
result = None
for csv_list in aDict.values():
    aList = csv_list.split(',')
    if result is None:
        result = set(aList)
    else:
        result = result & set(aList)
print result
Don
  • 16,928
  • 12
  • 63
  • 101
0

Since set.intersection() accepts any number of sets, you can make do without any use of reduce():

set.intersection(*(set(v.split(",")) for v in aDict.values()))

Note that this version won't work for an empty aDict.

If you are using Python 3, and your dictionary values are bytes objects rather than strings, just split at b"," instead of ",".

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841