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

Discussion in 'Python' started by macm, Nov 9, 2010.

  1. macm

    macm Guest

    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
     
    macm, Nov 9, 2010
    #1
    1. Advertisements

  2. macm

    Peter Otten Guest

    ((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.
    I'm trying to set new standards in readability ;)
     
    Peter Otten, Nov 9, 2010
    #2
    1. Advertisements

  3. macm

    John Nagle Guest

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

    John Nagle
     
    John Nagle, Nov 9, 2010
    #3
  4. macm

    Terry Reedy Guest

    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]}
     
    Terry Reedy, Nov 9, 2010
    #4
  5. 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.
     
    D'Arcy J.M. Cain, Nov 9, 2010
    #5
  6. macm

    macm Guest

    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

     
    macm, Nov 9, 2010
    #6
  7. How come Python itself doesn’t display things that way?
     
    Lawrence D'Oliveiro, Nov 10, 2010
    #7
  8. macm

    Paul Rudin Guest

    try: pprint.pprint(dict1)
     
    Paul Rudin, Nov 10, 2010
    #8
  9. macm

    macm Guest

    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

    .... 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
    ....

    Best Regards

    Mario



     
    macm, Nov 10, 2010
    #9
  10. macm

    macm Guest

    .... 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
    ....

    but how I pass d[x] and make the filter?
    but should be {'ac': [1, 3, '79b'], 'ab': [2]}

    Best Regards

    Mario



     
    macm, Nov 10, 2010
    #10
  11. Hello,

    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:
     
    Alexander Gattin, Nov 11, 2010
    #11
  12. 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:
     
    Alexander Gattin, Nov 11, 2010
    #12
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.