3

I'm a perl scripter working in python and need to know a way to do the following perl in python.

$Hash{$key1}[$index_value]{$key2} = $value;

I have seen the stackoverflow question here: List of dictionaries, in a dictionary - in Python

I still don't understand what self.rules is doing or if it works for my solution.

My data will be coming from files, and will I will be using regexes to capture to temporary variables until ready to store in the data structure. If you need to ask, the order related to the $index_value is important and would like to be maintained as an integer.

Any suggestions are appreciated or if you think I need to rethink data structures with Python that would be helpful.

Community
  • 1
  • 1
Andy
  • 31
  • 1
  • What exactly are you trying to do? Do you already have a dict of lists of dicts and you just need to assign to it? Do you need to initialize the structure? Do you need to add to the structure as you iterate through elements? – Roger Fan Aug 21 '14 at 22:16
  • @RogerFan I need to initialize the structure and I will need to add to the structure. Let say for every line of the file I capture both keys, the index, and the data value. I place the first line in the dicts of lists of dicts, and on the second line I do the same, etc. Does this help what I'm trying to do? – Andy Aug 22 '14 at 00:33
  • @Andy: Does the index increment by one every time? – unutbu Aug 22 '14 at 00:34
  • @unutbu yes, I'd like it to behave just like a regular list, only instead of values they are dictionaries. – Andy Aug 22 '14 at 01:23

2 Answers2

1

You want h to be a dictionary (h because hash is Python builtin):

h = {}

Now, h[key] should be a list (for some suitable key):

key = 'key'
L = h[key] = []

I set L to refer to h[key] so that the next explanation is easier.

Now, each element of L is a dictionary:

value1 = {'key2': 42, 'key3': 6*9}
L.append(value1)
value2 = {'key3': 'some other value'}
L.append(value2)

Now, you can index h the way you want:

h[key][0]['key2']
h[key][1]['key3']

You can append to the list:

h[key].append({})

etc.

Is this what you want?

Alok--
  • 724
  • 3
  • 10
  • Seems this is what he needs. I just want to add a little more details since OP is a perl guy: Python equivalent of a perl hash is dictionary. In perl you access the hash values by $hash{'key'} or $hash->{'key'} but in python you do dict['key']. So you basically use square brackets both for lists(~perl arrays) and dictionaries(~ perl hashes) the difference is what's inside the brackets. For dictionary it is key and for list it is index. – user3885927 Aug 21 '14 at 22:26
  • @user3885927 Ok... I think this makes sense, however I might need to reconsider because I'm using stackoverflow-er nosklo's AutoVivification class to mimic Perl's hash functionality. What would be the proper way to create this structure in python. Edit: So say I have all four piece of info in variables, how would I add this. Thanks -Andy – Andy Aug 22 '14 at 00:24
  • @Andy, I assume you are asking an equivalent for "$Hash{$key1}[$index_value]{$key2} = $value;" If a is your AutoVivification object you would simply do a[key1][index_value][key2]=value. – user3885927 Aug 22 '14 at 16:40
  • @user3885927 I am ask the equivalent for $Hash{$key1}[$index_value]{$key2} = $value, I just saw something when creating a dict of dicts and coming from perl that this class will behave like perl hashes of hashes. Based on the comments here, I will need to drop this class. And try one of the above. – Andy Aug 22 '14 at 20:46
1

The direct Python equivalent of:

$Hash{$key1}[$index_value]{$key2} = $value;

is the following:

Hash[key1][index_value][key2] = value

Unfortunately, in Python, unlike Perl, this won't work when key1 doesn't already exist in Hash or when index_value is out of range of Hash[key1]. To handle both of these cases, you need to do something like:

lst1 = Hash.setdefault(key1, [])
if index_value >= len(lst1):
    for _ in range(len(lst1), index_value+1):
        lst1.append({})
lst1[index_value][key2] = value
jwodder
  • 54,758
  • 12
  • 108
  • 124