Learning Pyhton - Functional Programming - How intersect/differencetwo dict with dict/values? fast!

M

macm

Hi Folks,

dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],
54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],
12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':
[[9],34]}
dict3 = {'ac':[[1,3,67,'gf'],12],'at':[[2,4,50,42,'c4'],12],'as':
[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34]}
intersect = filter(dict1.has_key, dict2.keys())
intersect
result:
['ax', 'ac', 'ab']

expect result dict1 intersection with dict2
{'ac':[1,3,'79b'], 'ab':[2,'d3']} # look last key/value 'ax' (dict1,
dict2) even intersec a key but not values from list so not valid

and difference from dict3
dict3 = {'ac':[[1,3,67,'gf'],12],'at':[[2,4,50,42,'c4'],12],'as':
[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34]}

result from (intersect - dict3)
{'ac':['79b'], 'ab':[2,'d3']}

Thanks in advance!

Before someone blame me.

Yes I am trying learn python Functional Programming! ; )

Best Regards

macm
 
P

Peter Otten

macm said:
Hi Folks,

dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],
54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],
12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':
[[9],34]}
dict3 = {'ac':[[1,3,67,'gf'],12],'at':[[2,4,50,42,'c4'],12],'as':
[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34]}
intersect = filter(dict1.has_key, dict2.keys())
intersect
result:
['ax', 'ac', 'ab']

expect result dict1 intersection with dict2
{'ac':[1,3,'79b'], 'ab':[2,'d3']} # look last key/value 'ax' (dict1,
dict2) even intersec a key but not values from list so not valid

and difference from dict3
dict3 = {'ac':[[1,3,67,'gf'],12],'at':[[2,4,50,42,'c4'],12],'as':
[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34]}

result from (intersect - dict3)
{'ac':['79b'], 'ab':[2,'d3']}

Thanks in advance!

Before someone blame me.

Yes I am trying learn python Functional Programming! ; )
dict((k, v) for k, v in ((k, [a for a in v if a in w]) for k, v, w in
((k, v[0], set(dict2[k][0])) for k, v in dict1.iteritems() if k in dict2))
if v)
{'ac': [1, 3, '79b'], 'ab': [2]}

Replacing the genexps with map/filter/lambda is left as an exercise.
Before someone blame me.

I'm trying to set new standards in readability ;)
 
J

John Nagle

Hi Folks,

dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],
54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],
12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':
[[9],34]}
dict3 = {'ac':[[1,3,67,'gf'],12],'at':[[2,4,50,42,'c4'],12],'as':
[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34]}
intersect = filter(dict1.has_key, dict2.keys())
intersect
result:
['ax', 'ac', 'ab']

When you've spent a year maintaining and fixing code written
by others, come back and we'll talk.

John Nagle
 
T

Terry Reedy

On 11/9/2010 9:32 AM, macm wrote:
dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],
54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}

To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:

dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
'ac': [[1,3,'78a','79b'], 54],
'ad': [[56,57,58,59], 34],
'ax': [[56,57,58,59], 34]}
 
D

D'Arcy J.M. Cain

To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:

dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
'ac': [[1,3,'78a','79b'], 54],
'ad': [[56,57,58,59], 34],
'ax': [[56,57,58,59], 34]}

I have been learning to like this form:

dict1 = dict(
ab = [[1,2,3,'d3','d4',5], 12],
ac = [[1,3,'78a','79b'], 54],
ad = [[56,57,58,59], 34],
ax = [[56,57,58,59], 34],
)

Of course, it only works when all the keys are strings.
 
M

macm

Sorry Mr. Nagle and Folks

I had a bad day today.

I need forward but with fever, a grasp and headache is hard.

You are absolute right, I was rude and I ask your pardon.

About my code, sorry I thought was the best way to copy and paste in
python console.

Best Regards

macm

To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:
dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
          'ac': [[1,3,'78a','79b'], 54],
          'ad': [[56,57,58,59], 34],
          'ax': [[56,57,58,59], 34]}

I have been learning to like this form:

dict1 = dict(
  ab = [[1,2,3,'d3','d4',5], 12],
  ac = [[1,3,'78a','79b'], 54],
  ad = [[56,57,58,59], 34],
  ax = [[56,57,58,59], 34],
)

Of course, it only works when all the keys are strings.
 
L

Lawrence D'Oliveiro

Terry Reedy said:
To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:

dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
'ac': [[1,3,'78a','79b'], 54],
'ad': [[56,57,58,59], 34],
'ax': [[56,57,58,59], 34]}

How come Python itself doesn’t display things that way?
 
P

Paul Rudin

Lawrence D'Oliveiro said:
Terry Reedy said:
To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:

dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
'ac': [[1,3,'78a','79b'], 54],
'ad': [[56,57,58,59], 34],
'ax': [[56,57,58,59], 34]}

How come Python itself doesn’t display things that way?

try: pprint.pprint(dict1)
 
M

macm

Hi Folks

I am studing yet (with fever, grasp and headache).

I know I can do better, but first I should learn more about
"dictionary comprehension syntax" in python 2.65

dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':[[9],34]}

# Arnaud Delobelle
.... def intersectList(iterables):
.... nexts = [iter(iterable).next for iterable in iterables]
.... v = [next() for next in nexts]
.... while True:
.... for i in xrange(1, len(v)):
.... while v[0] > v:
.... v = nexts()
.... if v[0] < v: break
.... else:
.... yield v[0]
.... v[0] = nexts[0]()
........ d = {}
.... e = {}
.... r1 = filter(s1.has_key, s2.keys())
.... for x in r1:
.... d[x] = list(intersectList([s1[x][0],s2[x][0]]))
.... if len(d[x]) > 0:
.... e[x] = d[x]
.... return e
....
intersect(dict1,dict2) {'ac': [1, 3, '79b'], 'ab': [2]}


Best Regards

Mario



Lawrence D'Oliveiro said:
In message <[email protected]>, Terry Reedy
wrote:
To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:
dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
          'ac': [[1,3,'78a','79b'], 54],
          'ad': [[56,57,58,59], 34],
          'ax': [[56,57,58,59], 34]}
How come Python itself doesn’t display things that way?

try: pprint.pprint(dict1)
 
M

macm

.... and this works!
.... d = {}
.... e = {}
.... r1 = filter(s1.has_key, s2.keys())
.... for x in r1:
.... d[x]= filter(lambda z:z in s1[x][0],s2[x][0])
.... if len(d[x]) > 0:
.... e[x] = d[x]
.... return e
....
intersect(dict1,dict2) {'ac': [1, 3, '79b'], 'ab': [2]}


but how I pass d[x] and make the filter?
result = [filter(lambda z:z in dict1[x][0],dict2[x][0]) for x in filter(dict1.has_key, dict2.keys())]
result [[], [1, 3, '79b'], [2]]

but should be {'ac': [1, 3, '79b'], 'ab': [2]}

Best Regards

Mario



Hi Folks

I am studing yet (with fever, grasp and headache).

I know I can do better, but first I should learn more about
"dictionary comprehension syntax" in python 2.65
dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':[[9],34]}
# Arnaud Delobelle

... def intersectList(iterables):
...     nexts = [iter(iterable).next for iterable in iterables]
...     v = [next() for next in nexts]
...     while True:
...         for i in xrange(1, len(v)):
...             while v[0] > v:
...                 v = nexts()
...             if v[0] < v: break
...         else:
...             yield v[0]
...         v[0] = nexts[0]()
...>>> defintersect(s1, s2):

...     d = {}
...     e = {}
...     r1 = filter(s1.has_key, s2.keys())
...     for x in r1:
...         d[x] = list(intersectList([s1[x][0],s2[x][0]]))
...         if len(d[x]) > 0:
...             e[x] = d[x]
...     return e
...>>>intersect(dict1,dict2)

{'ac': [1, 3, '79b'], 'ab': [2]}



Best Regards

Mario

Lawrence D'Oliveiro said:
In message <[email protected]>, Terry Reedy
wrote:
To echo John Nagle's point, if you want non-masochist volunteers to read
your code, write something readable like:
dict1 = {'ab': [[1,2,3,'d3','d4',5], 12],
          'ac': [[1,3,'78a','79b'], 54],
          'ad': [[56,57,58,59], 34],
          'ax': [[56,57,58,59], 34]}
How come Python itself doesn’t display things that way?
try: pprint.pprint(dict1)
 
A

Alexander Gattin

Hello,

dict1 = {'ab':[[1,2,3,'d3','d4',5],12],'ac':[[1,3,'78a','79b'],
54],'ad': [[56,57,58,59],34], 'ax': [[56,57,58,59],34]}
dict2 = {'ab':[[22,2,'a0','42s','c4','d3'],12],'ab':[[2,4,50,42,'c4'],
12],'ac':[[1,3,'79b',45,65,'er4'],54],'ae': [[56,57,58,59],34],'ax':
[[9],34]}

You have a problem here: key 'ab' is listed twice
in dict2 and only its second value is then
visible: [[2,4,50,42,'c4'], 12], so that I
couldn't get the desired {'ac':[1,3,'79b'],
'ab':[2,'d3']} intersection.

So, after I've found the problem, the desired
functional-style code emerges:
dict(filter(lambda t: t[1],
... map(lambda k: (k, filter(lambda v: v in dict2[k][0], dict1[k][0])),
... filter(dict2.has_key, dict1.iterkeys()))
... )
... )
{'ac': [1, 3, '79b'], 'ab': [2, 'd3']}
 
A

Alexander Gattin

functional-style code emerges:
dict(filter(lambda t: t[1],
... map(lambda k: (k, filter(lambda v: v in dict2[k][0], dict1[k][0])),
... filter(dict2.has_key, dict1.iterkeys()))
... )
... )

Sorry, the indentation for the above code
is plain wrong. I'm not accustomed to
lisp-indenting, and only have managed to produce
the next version below:
dict(filter(lambda t: t[1],
... map(lambda k: (k, filter(lambda v: v in dict2[k][0],
... dict1[k][0]
... )
... ),
... filter(dict2.has_key, dict1.iterkeys())
... )
... )
... )
{'ac': [1, 3, '79b'], 'ab': [2, 'd3']}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

corrupt zip files 10

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top