Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Less code on multi key dictionary initialization

I have such code (Python 2.7+):

target = "some_string_key1_key3_key5_key6"

some_dict = {
    'key1': 'value1',
    'key2': 'value1',
    'key3': 'value2',
    'key4': 'value2',
    'key5': 'value3',
    'kyy6': 'value4',
}

for k, v in some_dict.iteritems():
    target = target.replace(k, v)

As you can see, there are different keys using the same value (key1 and key2 / key3 and key4). All keys and values are strings in my case.

Is there any possibility to have less code on dictionary initialization and still get

for k, v in some_dict.iteritems()

behavior unchanged with only standart python 2.7 modules?

I tried multi_key_dict, but for me it is less convinient, because of slightly different syntax.

All I want to achieve is something like that:

new_cool_dict = {
    ['key1', 'key2', ]: 'value1',
    ['key3', 'key4', ]: 'value2',
    'key5': 'value3',
    'key6': 'value6',
}

for k, v in new_cool_dict.iteritems():
    target = target.replace(k, v)
like image 549
silent Avatar asked Sep 24 '26 14:09

silent


2 Answers

I'd find this to be less useful and readable, but you can use multiple assignments on one line:

some_dict = {
    'key5': 'value3',
    'kyy6': 'value4',
}
some_dict['key1'] = some_dict['key2'] = 'value1'
some_dict['key3'] = some_dict['key4'] = 'value2'

The alternative would be to build a factory function that expands tuple keys:

def expand_tuple_keys(d):
    result = {}
    for key, value in d.iteritems():
        if not hasattr(key, '__iter__'):
            key = (key,)
        result.update((k, value) for k in key)
    return result

then use:

new_cool_dict = expand_tuple_keys({
    ('key1', 'key2'): 'value1',
    ('key3', 'key4'): 'value2',
    'key5': 'value3',
    'key6': 'value6',
})

Demo:

>>> def expand_tuple_keys(d):
...     result = {}
...     for key, value in d.iteritems():
...         if not hasattr(key, '__iter__'):
...             key = (key,)
...         result.update((k, value) for k in key)
...     return result
... 
>>> expand_tuple_keys({
...     ('key1', 'key2'): 'value1',
...     ('key3', 'key4'): 'value2',
...     'key5': 'value3',
...     'key6': 'value6',
... })
{'key3': 'value2', 'key2': 'value1', 'key1': 'value1', 'key6': 'value6', 'key5': 'value3', 'key4': 'value2'}
like image 113
Martijn Pieters Avatar answered Sep 26 '26 03:09

Martijn Pieters


You could also define your dictionary the other way around for convenience:

my_dict = {
    'value1': ['key1', 'key2'],
    'value2': ['key3', 'key4'],
    'value3': ['key5']
}

And then convert it into a more usable representation:

>>> dict((k, v) for (v, l) in my_dict.iteritems() for k in l)
{'key1': 'value1',
 'key2': 'value1',
 'key3': 'value2',
 'key4': 'value2',
 'key5': 'value3'}
like image 45
eskaev Avatar answered Sep 26 '26 02:09

eskaev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!