dict slice in python (translating perl to python)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • hofer

    dict slice in python (translating perl to python)

    Hi,

    Let's take following perl code snippet:

    %myhash=( one =1 , two =2 , three =3 );
    ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
    print "$v1\n$v2\n$v2\ n";

    How do I translate the second line in a similiar compact way to
    python?

    Below is what I tried. I'm just interested in something more compact.

    mydict={ 'one' : 1 , 'two' : 2 , 'three' : 3 }
    # first idea, but still a little too much to type
    [v1,v2,v3] = [ mydict[k] for k in ['one','two','tw o']]

    # for long lists lazier typing,but more computational intensive
    # as split will probably be performed at runtime and not compilation
    time
    [v1,v2,v3] = [ mydict[k] for k in 'one two two'.split()]

    print "%s\n%s\n%s " %(v1,v2,v3)



    thanks for any ideas

  • Wojtek Walczak

    #2
    Re: dict slice in python (translating perl to python)

    On Wed, 10 Sep 2008 08:28:43 -0700 (PDT), hofer wrote:
    Hi,
    >
    Let's take following perl code snippet:
    >
    %myhash=( one =1 , two =2 , three =3 );
    ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
    print "$v1\n$v2\n$v2\ n";
    What about:
    >>myhash={'one' :1, 'two':2, 'three':3}
    >>map(myhash.ge t, ['one', 'two', 'two'])
    [1, 2, 2]
    >>>
    or, to make it more similar to perl's qw() thing:
    >>map(myhash.ge t, 'one two two'.split())
    [1, 2, 2]
    >>>
    ....but I think that using explicit list is more pythonic.
    Isn't it? ;)

    --
    Regards,
    Wojtek Walczak,
    Cena domeny: 4999 PLN (do negocjacji). Możliwość kupna na raty od 624.88 PLN miesięcznie. Oferta sprzedaży znajduje się w serwisie Aftermarket.pl, największej giełdzie domen internetowych w Polsce.

    Comment

    • Jon Clements

      #3
      Re: dict slice in python (translating perl to python)

      On 10 Sep, 16:28, hofer <bla...@dungeon .dewrote:
      Hi,
      >
      Let's take following perl code snippet:
      >
      %myhash=( one  =1    , two   =2    , three =3 );
      ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
      print "$v1\n$v2\n$v2\ n";
      >
      How do I translate the second line in a similiar compact way to
      python?
      >
      Below is what I tried. I'm just interested in something more compact.
      >
      mydict={ 'one'   : 1    , 'two'   : 2    , 'three' : 3 }
      # first idea, but still a little too much to type
      [v1,v2,v3] = [ mydict[k] for k in ['one','two','tw o']]
      >
      # for long lists lazier typing,but more computational intensive
      # as  split will probably be performed at runtime and not compilation
      time
      [v1,v2,v3] = [ mydict[k] for k in 'one two two'.split()]
      >
      print "%s\n%s\n%s " %(v1,v2,v3)
      >
      thanks for any ideas
      Another option [note I'm not stating it's preferred, but it would
      appear to be closer to some syntax that you'd prefer to use....]
      >>from operator import itemgetter
      >>x = { 'one' : 1, 'two' : 2, 'three' : 3 }
      >>itemgetter('o ne', 'one', 'two')(x)
      (1, 1, 2)

      hth
      Jon.

      Comment

      • Fredrik Lundh

        #4
        Re: dict slice in python (translating perl to python)

        B wrote:
        for a long list, you could try:
        result = [mydict[k] for k in mydict]
        or [mydict[k] for k in mydict.keys()]
        or [mydict[k] for k in mydict.iterkeys ()]
        and the point of doing that instead of calling mydict.values() is what?

        </F>

        Comment

        • B

          #5
          Re: dict slice in python (translating perl to python)

          Fredrik Lundh wrote:
          B wrote:
          >for a long list, you could try:
          >result = [mydict[k] for k in mydict]
          >or [mydict[k] for k in mydict.keys()]
          >or [mydict[k] for k in mydict.iterkeys ()]
          >
          and the point of doing that instead of calling mydict.values() is what?
          >
          </F>
          >
          It's more fun? Or if you want to sort by keys.

          Comment

          • Terry Reedy

            #6
            Re: dict slice in python (translating perl to python)

            hofer wrote:
            Let's take following perl code snippet:
            >
            %myhash=( one =1 , two =2 , three =3 );
            ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
            print "$v1\n$v2\n$v2\ n";
            >
            How do I translate the second line in a similiar compact way to
            python?
            >
            Below is what I tried. I'm just interested in something more compact.
            Python does not try to be as compact as Perl. Pythoneers generally
            consider that a feature. Anyway, the second Python version is
            asymtotically as compact as the Perl code, differing only by a small
            constant number of bytes while the code size grows.
            mydict={ 'one' : 1 , 'two' : 2 , 'three' : 3 }
            # first idea, but still a little too much to type
            [v1,v2,v3] = [ mydict[k] for k in ['one','two','tw o']]
            The initial brackets add nothing. "v1,v2,v3 =" does the same.
            >
            # for long lists lazier typing,but more computational intensive
            # as split will probably be performed at runtime and not compilation
            time
            You have spent and will spend more time posting and reading than the
            equivalent extra computation time this will take with any normal
            exchange rate and computation usage.
            [v1,v2,v3] = [ mydict[k] for k in 'one two two'.split()]
            This is a standard idiom for such things. If it bothers you, type "'one
            two two'.split()" into an interactive window and 'in a blink' get
            ['one', 'two', 'two'], which you can cut and paste into a program.
            print "%s\n%s\n%s " %(v1,v2,v3)
            However, more that about 3 numbered variables in a Python program
            suggest the possibility of a better design, such as leaving the values
            in a list vee and accessing them by indexing.

            Terry Jan Reedy

            Comment

            • Duncan Booth

              #7
              Re: dict slice in python (translating perl to python)

              hofer <blabla@dungeon .dewrote:
              Let's take following perl code snippet:
              >
              %myhash=( one =1 , two =2 , three =3 );
              ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
              print "$v1\n$v2\n$v2\ n";
              >
              How do I translate the second line in a similiar compact way to
              python?
              One point I haven't seen in the other responses is that, at least for the
              example given, you don't need the second line at all:

              mydict={ 'one': 1, 'two': 2, 'three': 3 }
              print "%(one)s\n%(two )s\n%(two)s" % mydict

              --
              Duncan Booth http://kupuguy.blogspot.com

              Comment

              • Nick Craig-Wood

                #8
                Re: dict slice in python (translating perl to python)

                hofer <blabla@dungeon .dewrote:
                Let's take following perl code snippet:
                >
                %myhash=( one =1 , two =2 , three =3 );
                ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
                print "$v1\n$v2\n$v2\ n";
                >
                How do I translate the second line in a similiar compact way to
                python?
                >
                Below is what I tried. I'm just interested in something more compact.
                >
                mydict={ 'one' : 1 , 'two' : 2 , 'three' : 3 }
                # first idea, but still a little too much to type
                [v1,v2,v3] = [ mydict[k] for k in ['one','two','tw o']]
                >
                # for long lists lazier typing,but more computational intensive
                # as split will probably be performed at runtime and not compilation
                time
                [v1,v2,v3] = [ mydict[k] for k in 'one two two'.split()]
                As an ex-perl programmer and having used python for some years now,
                I'd type the explicit

                v1,v2,v3 = mydict['one'], mydict['two'], mydict['two'] # 54 chars

                Or maybe even

                v1 = mydict['one'] # 54 chars
                v2 = mydict['two']
                v3 = mydict['two']

                Either is only a couple more characters to type. It is completely
                explicit and comprehensible to everyone, in comparison to

                v1,v2,v3 = [ mydict[k] for k in ['one','two','tw o']] # 52 chars
                v1,v2,v3 = [ mydict[k] for k in 'one two two'.split()] # 54 chars

                Unlike perl, it will also blow up if mydict doesn't contain 'one'
                which may or may not be what you want.

                --
                Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

                Comment

                • Steven D'Aprano

                  #9
                  Re: dict slice in python (translating perl to python)

                  On Thu, 11 Sep 2008 03:36:35 -0500, Nick Craig-Wood wrote:
                  As an ex-perl programmer and having used python for some years now, I'd
                  type the explicit
                  >
                  v1,v2,v3 = mydict['one'], mydict['two'], mydict['two'] # 54 chars
                  >
                  Or maybe even
                  >
                  v1 = mydict['one'] # 54 chars
                  v2 = mydict['two']
                  v3 = mydict['two']
                  >
                  Either is only a couple more characters to type.
                  But that's an accident of the name you have used. Consider:

                  v1,v2,v3 = section_heading _to_table_index['one'], \
                  section_heading _to_table_index['two'], \
                  section_heading _to_table_index['two'] # 133 characters

                  versus:

                  v1,v2,v3 = [section_heading _to_table_index[k] for k in
                  ['one','two','tw o']] # 75 characters



                  It also fails the "Don't Repeat Yourself" principle, and it completely
                  fails to scale beyond a handful of keys.

                  Out of interest, on my PC at least the list comp version is significantly
                  slower than the explicit assignments. So it is a micro-optimization that
                  may be worth considering if needed -- but at the cost of harder to
                  maintain code.

                  It is completely
                  explicit and comprehensible to everyone, in comparison to
                  >
                  v1,v2,v3 = [ mydict[k] for k in ['one','two','tw o']] # 52 chars
                  v1,v2,v3 = [ mydict[k] for k in 'one two two'.split()] # 54 chars
                  That's a matter for argument. I find the list comprehension perfectly
                  readable and comprehensible, and in fact I had to read your explicit
                  assignments twice to be sure I hadn't missed something. But I accept that
                  if you aren't used to list comps, they might look a little odd.



                  --
                  Steven

                  Comment

                  • hofer

                    #10
                    Re: dict slice in python (translating perl to python)

                    Thanks a lot for all your answers.

                    There's quite some things I learnt :-)

                    [v1,v2,v3] = ...
                    can be typed as
                    v1,v2,v3 = . . .

                    I also wasn't used to
                    map(myhash.get, ['one', 'two', 'two'])
                    itemgetter('one ', 'one', 'two')(x)

                    I also didn't know
                    print "%(one)s\n%(two )s\n%(two)s" % mydict


                    The reason I'd like to have a short statement for above is, that this
                    is for me basically just
                    some code, to name and use certain fields of a hash in i given code
                    section.

                    The real example would be more like:

                    name,age,countr y = itemgetter('nam e age country'.split( ))(x) # or any
                    of my above versions

                    # a lot of code using name / age / country



                    thanks a gain and bye

                    H
                    On Sep 10, 5:28 pm, hofer <bla...@dungeon .dewrote:
                    Let's take following perl code snippet:
                    >
                    %myhash=( one  =1    , two   =2    , three =3 );
                    ($v1,$v2,$v3) = @myhash{qw(one two two)}; # <-- line of interest
                    print "$v1\n$v2\n$v2\ n";
                    >
                    How do I translate the second line in a similiar compact way to
                    python?
                    >
                    Below is what I tried. I'm just interested in something more compact.
                    >
                    mydict={ 'one'   : 1    , 'two'   : 2    , 'three' : 3 }
                    # first idea, but still a little too much to type
                    [v1,v2,v3] = [ mydict[k] for k in ['one','two','tw o']]
                    >
                    # for long lists lazier typing,but more computational intensive
                    # as  split will probably be performed at runtime and not compilation
                    time
                    [v1,v2,v3] = [ mydict[k] for k in 'one two two'.split()]
                    >
                    print "%s\n%s\n%s " %(v1,v2,v3)

                    Comment

                    • hofer

                      #11
                      Re: dict slice in python (translating perl to python)

                      On Sep 11, 10:36 am, Nick Craig-Wood <n...@craig-wood.comwrote:
                      >I'd type the explicit
                      >
                      v1,v2,v3 = mydict['one'], mydict['two'], mydict['two'] # 54 chars Either is only a couple more
                      characters to type.  It is completely
                      explicit and comprehensible to everyone, in comparison to
                      >
                        v1,v2,v3 = [ mydict[k] for k in ['one','two','tw o']] # 52 chars
                        v1,v2,v3 = [ mydict[k] for k in 'one two two'.split()] # 54 chars
                      >
                      Unlike perl, it will also blow up if mydict doesn't contain 'one'
                      which may or may not be what you want.
                      >
                      Is your above solution robust against undefined keys.
                      In my example it would'nt be a problem. The dict would be fully
                      populated, but I'm just curious.


                      Comment

                      • bearophileHUGS@lycos.com

                        #12
                        Re: dict slice in python (translating perl to python)

                        hofer:
                        The real example would be more like:
                        name,age,countr y = itemgetter('nam e age country'.split( ))(x) # or any
                        of my above versions
                        That solution is very clever, and the inventor smart, but it's too
                        much out of standard and complex to be used in normal real code.
                        Learning tricks is useful, but then in real code you have to use then
                        only once in a while. A list comp is quite more easy to understand for
                        Python programmers.

                        Bye,
                        bearophile

                        Comment

                        • Fredrik Lundh

                          #13
                          Re: dict slice in python (translating perl to python)

                          hofer wrote:
                          The real example would be more like:
                          >
                          name,age,countr y = itemgetter('nam e age country'.split( ))(x)
                          ouch.

                          if you do this a lot (=more than once), just wrap your dictionaries in a
                          simple attribute proxy, and use plain attribute access. that is, given

                          class AttributeWrappe r:
                          def __init__(self, obj):
                          self.obj = obj
                          def __getattr__(sel f, name):
                          try:
                          return self.obj[name]
                          except KeyError:
                          raise AttributeError( name)

                          or, shorter but less obvious and perhaps a bit too clever for a
                          beginning Pythoneer:

                          class AttributeWrappe r:
                          def __init__(self, obj):
                          self.__dict__.u pdate(obj)

                          you can do
                          >>some_data = dict(name="Some Name", age=123, country="SE")
                          >>some_data
                          {'country': 'SE', 'age': 123, 'name': 'Some Name'}
                          >>this = AttributeWrappe r(some_data)
                          >>this.name
                          'Some Name'
                          >>this.age
                          123
                          >>this.countr y
                          'SE'

                          and, if you must, assign the attributes to local variables like this:
                          >>name, age, country = this.name, this.age, this.country
                          >>name
                          'Some Name'
                          >>age
                          123
                          >>country
                          'SE'
                          >>>
                          (the next step towards true Pythonicness would be to store your data in
                          class instances instead of dictionaries in the first place, but one step
                          at a time...)

                          </F>

                          Comment

                          • Aaron \Castironpi\ Brady

                            #14
                            Re: dict slice in python (translating perl to python)

                            On Sep 11, 10:52 am, hofer <bla...@dungeon .dewrote:
                            On Sep 11, 10:36 am, Nick Craig-Wood <n...@craig-wood.comwrote:
                            >
                            I'd type the explicit
                            >
                             v1,v2,v3 = mydict['one'], mydict['two'], mydict['two'] # 54 chars Either is only a couple more
                            characters to  type.  It is completely
                            explicit and comprehensible to everyone, in comparison to
                            >
                              v1,v2,v3 = [ mydict[k] for k in ['one','two','tw o']] # 52 chars
                              v1,v2,v3 = [ mydict[k] for k in 'one two two'.split()] # 54 chars
                            >
                            Unlike perl, it will also blow up if mydict doesn't contain 'one'
                            which may or may not be what you want.
                            >
                            Is your above solution robust against undefined keys.
                            In my example it would'nt be a problem. The dict would be fully
                            populated, but I'm just curious.
                            If undefined keys aren't a problem, then there's a value you expect
                            from them. Use

                            v1,v2,v3 = [ mydict.get(k,de fault) for k in 'one two two'.split()]

                            where default is the value you're expecting.

                            Comment

                            • MRAB

                              #15
                              Re: dict slice in python (translating perl to python)

                              On Sep 11, 6:11 pm, Fredrik Lundh <fred...@python ware.comwrote:
                              [snip]
                              (the next step towards true Pythonicness would be to store your data in
                              class instances instead of dictionaries in the first place, but one step
                              at a time...)
                              >
                              Surely the word is "Pythonicit y"? :-)

                              Comment

                              Working...