Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > dict slice in python (translating perl to python)

Reply
Thread Tools

dict slice in python (translating perl to python)

 
 
hofer
Guest
Posts: n/a
 
      09-10-2008
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','two']]

# 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

 
Reply With Quote
 
 
 
 
Jon Clements
Guest
Posts: n/a
 
      09-10-2008
On 10 Sep, 16:28, hofer <(E-Mail Removed)> 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";
>
> 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','two']]
>
> # 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('one', 'one', 'two')(x)

(1, 1, 2)

hth
Jon.

 
Reply With Quote
 
 
 
 
B
Guest
Posts: n/a
 
      09-10-2008
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()]
this won't give you the same order as your code though, if you want them
sorted you can use the sorted function:
[mydict[k] for k in sorted(x)] (or sorted(x.etc))



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";
>
> 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','two']]
>
> # 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
>

 
Reply With Quote
 
Fredrik Lundh
Guest
Posts: n/a
 
      09-10-2008
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>

 
Reply With Quote
 
B
Guest
Posts: n/a
 
      09-10-2008
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.
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      09-10-2008
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','two']]


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

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-11-2008
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','two']] # 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','two']] # 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
 
Reply With Quote
 
hofer
Guest
Posts: n/a
 
      09-11-2008
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,country = itemgetter('name 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 <(E-Mail Removed)> 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.
>
> 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','two']]
>
> # 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)



 
Reply With Quote
 
hofer
Guest
Posts: n/a
 
      09-11-2008
On Sep 11, 10:36*am, Nick Craig-Wood <(E-Mail Removed)> wrote:
>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','two']] # 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.


 
Reply With Quote
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      09-11-2008
hofer:
> The real example would be more like:
> name,age,country = itemgetter('name 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dict.items() vs dict.iteritems and similar questions Drew Python 19 03-15-2007 09:23 PM
dict.has_key(x) versus 'x in dict' Paul Melis Python 48 12-15-2006 05:55 PM
Inconsistency in dictionary behaviour: dict(dict) not calling __setitem__ Almad Python 8 12-14-2006 07:37 PM
dict!ident as equivalent of dict["ident"] Alexander Kozlovsky Python 5 05-22-2006 08:06 AM
Re: dict->XML->dict? Or, passing small hashes through text? Skip Montanaro Python 0 08-15-2003 03:46 PM



Advertisments