Dict Comprehension ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ernst-Ludwig Brust

    Dict Comprehension ?

    Given 2 Number-Lists say l0 and l1,
    count the various positiv differences between the 2 lists

    the following part works:

    dif=[abs(x-y) for x in l0 for y in l1]
    da={}
    for d in dif: da[d]=da.get(d,0)+1

    i wonder, if there is a way, to avoid the list dif

    Ernst-Ludwig Brust


  • bearophileHUGS@lycos.com

    #2
    Re: Dict Comprehension ?

    Ernst-Ludwig Brust:
    Given 2 Number-Lists say l0 and l1,
    count the various positiv differences between the 2 lists
    >...
    i wonder, if there is a way, to avoid the list dif
    Instead of creating the list (array) dif, you can create a lazy
    iterator. Then you can fed it to a set.

    Bye,
    bearophile

    Comment

    • pruebauno@latinmail.com

      #3
      Re: Dict Comprehension ?

      On Oct 6, 8:59 am, "Ernst-Ludwig Brust" <seinnix...@onl ine.dewrote:
      Given 2 Number-Lists say l0 and l1,
      count the various positiv differences between the 2 lists
      >
      the following part works:
      >
      dif=[abs(x-y) for x in l0 for y in l1]
      da={}
      for d in dif: da[d]=da.get(d,0)+1
      >
      i wonder, if there is a way, to avoid the list dif
      >
      Ernst-Ludwig Brust
      from collections import defaultdict
      da=defaultdict( int)
      for x in [10]:
      for y in [11]:
      da[abs(x-y)]+=1

      Comment

      • Ben Finney

        #4
        Re: Dict Comprehension ?

        "Ernst-Ludwig Brust" <seinnixgud@onl ine.dewrites:
        Given 2 Number-Lists say l0 and l1,
        count the various positiv differences between the 2 lists
        >
        the following part works:
        >
        dif=[abs(x-y) for x in l0 for y in l1]
        da={}
        for d in dif: da[d]=da.get(d,0)+1
        >
        i wonder, if there is a way, to avoid the list dif
        You can iterate over any iterable. A generator is iterable; and you
        can (among other ways) create a generator with a generator
        expression.

        Fortunately, you already know how to write any generator expression:
        it's the same as a list comprehension, but without the square
        brackets.

        So, instead of making a list of differences and iterating over it::
        >>seq_a = [15, 17, 26]
        >>seq_b = [14, 17, 22]
        >>diffs = [abs(a - b) for a in seq_a for b in seq_b]
        >>diff_accumula tor = {}
        >>for diff in diffs:
        ... diff_accumulato r[diff] = diff_accumulato r.get(diff, 0) + 1
        ...
        >>diff_accumula tor
        {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

        you can skip the intermediate list creation and iterate over the
        generator made by an identical generator expression::
        >>seq_a = [15, 17, 26]
        >>seq_b = [14, 17, 22]
        >>diff_accumula tor = {}
        >>for diff in (abs(a - b) for a in seq_a for b in seq_b):
        ... diff_accumulato r[diff] = diff_accumulato r.get(diff, 0) + 1
        ...
        >>diff_accumula tor
        {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

        If you wanted to avoid starting the dict empty and writing the ‘for’
        loop yourself, you could even create your dict from a generator (the
        dict type can make a new dict from any key+value iterable) with the
        help of the standard library ‘itertools’ module::
        >>import itertools
        >>seq_a = [15, 17, 26]
        >>seq_b = [14, 17, 22]
        >>diffs = [abs(a - b) for a in seq_a for b in seq_b]
        >>diff_accumula tor = dict(
        ... (diff, len(list(items) ))
        ... for (diff, items) in itertools.group by(diffs)
        ... )
        >>diff_accumula tor
        {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

        This also, of course, benefits from the earlier approach to iterate
        over the diffs directly instead of an intermediate list::
        >>import itertools
        >>seq_a = [15, 17, 26]
        >>seq_b = [14, 17, 22]
        >>diff_accumula tor = dict(
        ... (diff, len(list(items) ))
        ... for (diff, items) in itertools.group by(
        ... abs(a - b) for a in seq_a for b in seq_b
        ... )
        ... )
        >>diff_accumula tor
        {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 1, 9: 1, 12: 1}

        So, generator expressions can be a powerful way to clarify the purpose
        of a section of code. They can be over-used, though: don't use them
        unless they actually *do* clarify the code; sometimes an explicit
        looping construct is clearer.

        --
        \ “Like the creators of sitcoms or junk food or package tours, |
        `\ Java's designers were consciously designing a product for |
        _o__) people not as smart as them.” —Paul Graham |
        Ben Finney

        Comment

        • Ernst-Ludwig Brust

          #5
          Re: Dict Comprehension ?

          <bearophileHUGS @lycos.comschri eb im Newsbeitrag
          news:5b9d41e1-4928-4fb5-b79d-4de2d70ddb66@m7 4g2000hsh.googl egroups.com...
          >
          Instead of creating the list (array) dif, you can create a lazy
          iterator. Then you can fed it to a set.
          Thangs,
          this idea is not only less storage-consuming but even faster
          than the "List-Version".
          But, i used the idea of pruebauno,
          as this is faster.

          Ernst-Ludwig Brust


          Comment

          • Ernst-Ludwig Brust

            #6
            Re: Dict Comprehension ?

            "Ben Finney" <bignose+hate s-spam@benfinney. id.auschrieb im Newsbeitrag
            news:874p3pmepu .fsf@benfinney. id.au...
            "Ernst-Ludwig Brust" <seinnixgud@onl ine.dewrites:
            >
            So, generator expressions can be a powerful way to clarify the purpose
            of a section of code. They can be over-used, though: don't use them
            unless they actually *do* clarify the code; sometimes an explicit
            looping construct is clearer.
            Thangs,
            my opinion was, that "one-statement-constructions" are
            much faster then f.e. explicit loops.
            But,
            now i know, with Python, this is not allways true.

            Ernst-Ludwig Brust


            Comment

            • Ernst-Ludwig Brust

              #7
              Re: Dict Comprehension ?

              <pruebauno@lati nmail.comschrie b im Newsbeitrag
              news:7cfd6944-955b-4f23-99f9-d52615abd909@75 g2000hso.google groups.com...
              >
              from collections import defaultdict
              da=defaultdict( int)
              for x in [10]:
              for y in [11]:
              da[abs(x-y)]+=1
              Thangs,
              collections are a real good idea.
              I will use this version.

              Ernsst-Ludwwig Brust


              Comment

              Working...