[Tutor] creating dict of dict : similar to perl hash of hash

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

[Tutor] creating dict of dict : similar to perl hash of hash

Abhishek Pratap
Hi Guys

I am looking for a way to build dictionaries of dict in python. 

For example in perl I could do

my $hash_ref = {};
$hash->{$a}->{$b}->{$c} = "value";
if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}

Can I do something similar with dictionaries in Python.


Thanks
-Abhi



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Martin A. Brown-4

Hello there Abhi,

 : I am looking for a way to build dictionaries of dict in python.
 :
 : For example in perl I could do
 :
 : my $hash_ref = {};
 : $hash->{$a}->{$b}->{$c} = "value";
 : if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}

Autovivifying.  That's what the perl-heads call that.

 : Can I do something similar with dictionaries in Python.

I suspect you want to look into the collections module.  Here's an
example of how to use it to create a two-level dictionary with the
same autovivifying behaviour you are accustomed to in perl.

  >>> import collections
  >>> d = collections.defaultdict(collections.defaultdict)
  >>> a,b,c = range(3)
  >>> d[a][b] = c
  >>> d
  defaultdict(<type 'collections.defaultdict'>, {0: defaultdict(None, {1: 2})})

Have a look at the collections module.  See if that scratches your
itch.

Good luck,

-Martin

--
Martin A. Brown
http://linux-ip.net/
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

David Rock
In reply to this post by Abhishek Pratap
* Abhishek Pratap <[hidden email]> [2012-03-06 09:50]:

> Hi Guys
>
> I am looking for a way to build dictionaries of dict in python.
>
> For example in perl I could do
>
> my $hash_ref = {};
> $hash->{$a}->{$b}->{$c} = "value";
> if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}
>
> Can I do something similar with dictionaries in Python.
Absolutely.  Python is very good at using nested dicts.

dict = {}
dict['a'] ={}
dict['a']['b'] = {}
dict['a']['b']['c']= "value"


This is a bit brute force, but it illustrates that the intermediary keys
need to exist.  ie, if you try to assign directly, it won't work:

Type "help", "copyright", "credits" or "license" for more information.
>>> dict ={}
>>> dict['a']['b']['c'] = 'value'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  KeyError: 'a'

Since the key 'a' doesn't exist, it throws an exception.

Python is also more flexible than perl in nesting data because it
doesn't have to be the same data type.  You can nest variables, lists,
dicts, etc all at the same level:

dict = {}
dict['mylist'] = [1,2,3]
dict['mystring'] = 'string'
dict['mynum'] = 4
dict['anotherdict'] = {}
dict['anotherdict']['anotherstring'] = 'string2'

--
David Rock
[hidden email]

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

attachment0 (197 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Joel Goldstick-2
In reply to this post by Abhishek Pratap
On Tue, Mar 6, 2012 at 12:50 PM, Abhishek Pratap <[hidden email]> wrote:

> Hi Guys
>
> I am looking for a way to build dictionaries of dict in python.
>
> For example in perl I could do
>
> my $hash_ref = {};
> $hash->{$a}->{$b}->{$c} = "value";
> if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}
>
> Can I do something similar with dictionaries in Python.
>
>
> Thanks
> -Abhi
>
>
Dictionaries can contain dictionaries in python:

>>> sub_d = {'key1':'value1'}
>>> d = {'subd1':sub_d}
>>> d
{'subd1': {'key1': 'value1'}}
>>> d['subd1']
{'key1': 'value1'}
>>>

The Python site has information  here:
http://docs.python.org/tutorial/datastructures.html#dictionaries

>
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



--
Joel Goldstick
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Alan Gauld
In reply to this post by Abhishek Pratap
On 06/03/12 17:50, Abhishek Pratap wrote:

> I am looking for a way to build dictionaries of dict in python.

Thats not a problem, you just nest them:

d1 = {key: value,...} # a single level dictionary

d2 = {key: d1, ...}   # a dictionary of dictionaries...

d3 = { key1: {key2: value, ...}, ...}  # and on one line

> For example in perl I could do
>
> my $hash_ref = {};
> $hash->{$a}->{$b}->{$c} = "value";
> if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}
>
> Can I do something similar with dictionaries in Python.

No idea, I haven't done any Perl for over 10 years.
What does that actually do?


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Thomas Maier
In reply to this post by David Rock
On Tue, Mar 6, 2012 at 8:19 PM, David Rock <[hidden email]> wrote:

> * Abhishek Pratap <[hidden email]> [2012-03-06 09:50]:
>> Hi Guys
>>
>> I am looking for a way to build dictionaries of dict in python.
>>
>> For example in perl I could do
>>
>> my $hash_ref = {};
>> $hash->{$a}->{$b}->{$c} = "value";
>> if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}
>>
>> Can I do something similar with dictionaries in Python.
>
> Absolutely.  Python is very good at using nested dicts.
>
> dict = {}
> dict['a'] ={}
> dict['a']['b'] = {}
> dict['a']['b']['c']= "value"
>
>
> This is a bit brute force, but it illustrates that the intermediary keys
> need to exist.  ie, if you try to assign directly, it won't work:
>
> Type "help", "copyright", "credits" or "license" for more information.
>>>> dict ={}
>>>> dict['a']['b']['c'] = 'value'
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  KeyError: 'a'
>
> Since the key 'a' doesn't exist, it throws an exception.
>
> Python is also more flexible than perl in nesting data because it
> doesn't have to be the same data type.  You can nest variables, lists,
> dicts, etc all at the same level:
>
> dict = {}
> dict['mylist'] = [1,2,3]
> dict['mystring'] = 'string'
> dict['mynum'] = 4
> dict['anotherdict'] = {}
> dict['anotherdict']['anotherstring'] = 'string2'
>
Hi David,
Mixed data types in nested data structure are possible in Perl as well:
%hash = ();
$hash{'mylist'} = [1,2,3];
$hash{'mystring'} = 'string';
$hash{'mynum'} = 4;
$hash{'anotherhash'} = {};
$hash{'anotherhash'}{'anotherstring'} = 'string2';

Thomas
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Alan Gauld
In reply to this post by Martin A. Brown-4
On 06/03/12 18:18, Martin A. Brown wrote:

>   : $hash->{$a}->{$b}->{$c} = "value";
>   : if (exists $hash->{$a}->{$b}->{$c} ){ print "found value"}
>
> Autovivifying.  That's what the perl-heads call that.

Aha!, that brought it back, now I know what it does...

>    >>>  import collections
>    >>>  d = collections.defaultdict(collections.defaultdict)
>    >>>  a,b,c = range(3)
>    >>>  d[a][b] = c
>    >>>  d
>    defaultdict(<type 'collections.defaultdict'>, {0: defaultdict(None, {1: 2})})

Unfortunately this fails at 3 levels as per the OP example.
The second level dict supplies a default value of None.

If you know the max number of depths you can do something
like this:

 >>> from collections import defaultdict as dd
 >>> d3 = dd(lambda : dd( lambda : dd() ) )
 >>> d3['a']['b']['c'] = 'value'
 >>> d3
defaultdict(<function <lambda> at 0x7f3aefa4e758>, {'a':
defaultdict(<function <lambda> at 0x7f3aefa4e6e0>, {'b':
defaultdict(None, {'c': 'value'})})})
 >>>

But it doesn't have the same dynamic depth that the Perl version has,
you need to know your maximum depth. The last level will always have the
default set to None.

You could create a class subclassed from defaultdict that would do it
though...

Unless of course somebody else can think of a more elegant solution.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

David Rock
In reply to this post by Thomas Maier
* Thomas Maier <[hidden email]> [2012-03-07 00:38]:

> Hi David,
> Mixed data types in nested data structure are possible in Perl as well:
> %hash = ();
> $hash{'mylist'} = [1,2,3];
> $hash{'mystring'} = 'string';
> $hash{'mynum'} = 4;
> $hash{'anotherhash'} = {};
> $hash{'anotherhash'}{'anotherstring'} = 'string2';
>
> Thomas
Hah.  Fair enough :-)

--
David Rock
[hidden email]

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

attachment0 (197 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] creating dict of dict : similar to perl hash of hash

Jerry Hill
In reply to this post by Alan Gauld
On Tue, Mar 6, 2012 at 6:21 PM, Alan Gauld <[hidden email]> wrote:
> But it doesn't have the same dynamic depth that the Perl version has, you
> need to know your maximum depth. The last level will always have the default
> set to None.
>
> You could create a class subclassed from defaultdict that would do it
> though...

It's a pretty easy class to write:

from collections import defaultdict

class recursivedefaultdict(defaultdict):
    def __init__(self):
        self.default_factory = type(self)

Given that bit of code, the OP's example looks a bit like this:

a = 1
b = 2
c = 'apples'

my_hash = recursivedefaultdict()
my_hash[a][b][c] = "value"
if my_hash[a][b][c]:
    print("found value")

--
Jerry
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor