简体   繁体   中英

python ordered dict with duplicates keys

I'm trying to write some python functions to generate a batch of input files, in which there is, for instance, this block:

***behavior
**energy_phase_1
ef_v 10
**energy_phase_2
ef_v 7.

So far i was using collections.OrderedDict, because order matters in this kind of input file). For instance,if there are two simulations in my batch:

inp_dict['***behavior'] = [ '', '']
inp_dict['**energy_phase_1'] = [ '', '']
inp_dict['**ef_v'] = [ '10', '20']
inp_dict['**energy_phase_2'] = [ '', '']
inp_dict['**ef_v'] = [ '7', '14']

And to write the file I would just do something like:

for s , n in enumerate(sim_list):
    ......some code...
    inp_file.write(' '.join([ key, val[s], '\n' for key, val in inp_dict.items]))

But as you can see, this is not enough, since it there are duplicates key in the dict.

So my question is: is there an ordered dict that allows for duplicate keys? For instance, if there exists dict['key']=1 and dict['key']=2, first call would return 1 and second 2?

Or, is there some clever and simple way to achieve want I want?

Thanks

The concept of duplicate key goes against the concept of dict.

If you need to maintain order and have duplicate keys I'd say you need to use another data structure. One possible solution would be using a list of tuples. Something like the following:

inp = list()

# Define your input as a list of tuples instead of as a dict

inp.append(('***behavior', ('', '')))
inp.append(('**energy_phase_1', ('', '')))
inp.append(('**ef_v', ('10', '20')))
inp.append(('**energy_phase_2', ('', '')))
inp.append(('**ef_v', ('7', '14')))

# You can have duplicate keys on the list and the order is preserved

output = "\n".join(["{key} {val}".format(key=t[0], val=t[1][0]).strip() for t in inp])

In this case the output variable would contain:

***behavior
**energy_phase_1
**ef_v 10
**energy_phase_2
**ef_v 7

If you need to access values by key (a dict-like functionality) you could use something like this:

def get_key_values(inp, key):

    filtr_by_key = filter(lambda t: True if t[0] == key else False, inp)
    return filtr_by_key

ef_v_values = get_key_values(inp, "**ef_v")

In this case the ef_v_values would contain only the values associated with the key **ef_v :

[('**ef_v', ('10', '20')), ('**ef_v', ('7', '14'))]

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM