473,387 Members | 1,379 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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','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

Sep 10 '08 #1
15 5848
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.get, ['one', 'two', 'two'])
[1, 2, 2]
>>>
or, to make it more similar to perl's qw() thing:
>>map(myhash.get, 'one two two'.split())
[1, 2, 2]
>>>
....but I think that using explicit list is more pythonic.
Isn't it? ;)

--
Regards,
Wojtek Walczak,
http://tosh.pl/gminick/
Sep 10 '08 #2
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','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.

Sep 10 '08 #3
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>

Sep 10 '08 #4
B
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.
Sep 10 '08 #5
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

Sep 10 '08 #6
hofer <bl****@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
Sep 11 '08 #7
hofer <bl****@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','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()]
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','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.

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Sep 11 '08 #8
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
Sep 11 '08 #9
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 <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','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)

Sep 11 '08 #10
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','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.
Sep 11 '08 #11
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
Sep 11 '08 #12
hofer wrote:
The real example would be more like:

name,age,country = itemgetter('name 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 AttributeWrapper:
def __init__(self, obj):
self.obj = obj
def __getattr__(self, 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 AttributeWrapper:
def __init__(self, obj):
self.__dict__.update(obj)

you can do
>>some_data = dict(name="Some Name", age=123, country="SE")
some_data
{'country': 'SE', 'age': 123, 'name': 'Some Name'}
>>this = AttributeWrapper(some_data)
this.name
'Some Name'
>>this.age
123
>>this.country
'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>

Sep 11 '08 #13
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','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.
If undefined keys aren't a problem, then there's a value you expect
from them. Use

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

where default is the value you're expecting.
Sep 11 '08 #14
On Sep 11, 6:11*pm, Fredrik Lundh <fred...@pythonware.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 "Pythonicity"? :-)
Sep 11 '08 #15
Steven D'Aprano <st****@REMOVE.THIS.cybersource.com.auwrote:
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.
If you have more than a handful of keys then you have a different
problem (far too many local variables) with your code I think!

DRY is a good principle. I still prefer the 3 explicit assignments
though ;-)
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.
A matter of taste certainly!

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Sep 12 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: cjl | last post by:
Hey all: I want to convert strings (ex. '3', '32') to strings with left padded zeroes (ex. '003', '032'), so I tried this: string1 = '32' string2 = "%03s" % (string1) print string2 >32
1
by: barnesc | last post by:
Hi again, Since my linear algebra library appears not to serve any practical need (I found cgkit, and that works better for me), I've gotten bored and went back to one of my other projects:...
8
by: vj | last post by:
I've been given a project which requires writing scripts that need to be run on over 3000 servers. Only about 15% of them have python installed on them. While all/most of them will have perl. ...
22
by: bearophileHUGS | last post by:
>From this interesting blog entry by Lawrence Oluyede: http://www.oluyede.org/blog/2006/07/05/europython-day-2/ and the Py3.0 PEPs, I think the people working on Py3.0 are doing a good job, I am...
7
by: Alexandre Guimond | last post by:
Hi all, i'm trying to deepcopy a slice object but i get the following error. Does anyone know a workaround? ActivePython 2.4.3 Build 12 (ActiveState Software Inc.) based on Python 2.4.3 (#69,...
10
by: mm | last post by:
Is there a Perl to Python converter? Or in general: a XY to Python converter? Is see, that Python is much better then Perl anyway. But for beginners, they whant to konw how is this done with...
7
by: Charles D Hixson | last post by:
I'm sure I've read before about how to construct prototypes in Python, but I haven't been able to track it down (or figure it out). What I basically want is a kind of class that has both class...
62
by: estherschindler | last post by:
This is part of a series examining the strengths and weaknesses of various scripting languages, with particular attention to enterprise (read: big company) use. You Used Python to Write WHAT?...
20
by: Pat | last post by:
I know it's not "fair" to compare language features, but it seems to me (a Python newbie) that appending a new key/value to a dict in Python is awfully cumbersome. In Python, this is the best...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.