user42298
user42298

Reputation: 1911

Extending python dictionary and changing key values

Assume I have a python dictionary with 2 keys.

dic = {0:'Hi!', 1:'Hello!'}

What I want to do is to extend this dictionary by duplicating itself, but change the key value. For example, if I have a code

dic = {0:'Hi!', 1:'Hello'}
multiplier = 3
def DictionaryExtend(number_of_multiplier, dictionary):
    "Function code"

then the result should look like

>>> DictionaryExtend(multiplier, dic)
>>> dic
>>> dic = {0:'Hi!', 1:'Hello', 2:'Hi!', 3:'Hello', 4:'Hi!', 5:'Hello'}

In this case, I changed the key values by adding the multipler at each duplication step. What's the efficient way of doing this?

Plus, I'm also planning to do the same job for list variable. I mean, extend a list by duplicating itself and change some values like above exmple. Any suggestion for this would be helpful, too!

Upvotes: 2

Views: 197

Answers (4)

Eric Duminil
Eric Duminil

Reputation: 54303

You don't need to extend anything, you need to pick a better input format or a more appropriate type.

As others have mentioned, you need a list, not an extended dict or OrderedDict. Here's an example with lines.txt:

1:Hello!
0: Hi.
2: pylang

And here's a way to parse the lines in the correct order:

def extract_number_and_text(line):
    number, text = line.split(':')
    return (int(number), text.strip())

with open('lines.txt') as f:
    lines = f.readlines()
    data = [extract_number_and_text(line) for line in lines]
    print(data)
    # [(1, 'Hello!'), (0, 'Hi.'), (2, 'pylang')]
    sorted_text = [text for i,text in sorted(data)]
    print(sorted_text)
    # ['Hi.', 'Hello!', 'pylang']
    print(sorted_text * 2)
    # ['Hi.', 'Hello!', 'pylang', 'Hi.', 'Hello!', 'pylang']
    print(list(enumerate(sorted_text * 2)))
    # [(0, 'Hi.'), (1, 'Hello!'), (2, 'pylang'), (3, 'Hi.'), (4, 'Hello!'), (5, 'pylang')]

Upvotes: 0

pylang
pylang

Reputation: 44615

You can try itertools to repeat the values and OrderedDict to maintain input order.

import itertools as it
import collections as ct


def extend_dict(multiplier, dict_):
    """Return a dictionary of repeated values."""
    return dict(enumerate(it.chain(*it.repeat(dict_.values(), multiplier))))

d = ct.OrderedDict({0:'Hi!', 1:'Hello!'})
multiplier = 3
extend_dict(multiplier, d)
# {0: 'Hi!', 1: 'Hello!', 2: 'Hi!', 3: 'Hello!', 4: 'Hi!', 5: 'Hello!'}

Regarding handling other collection types, it is not clear what output is desired, but the following modification reproduces the latter and works for lists as well:

def extend_collection(multiplier, iterable):
    """Return a collection of repeated values."""
    repeat_values = lambda x: it.chain(*it.repeat(x, multiplier))
    try:
        iterable = iterable.values()
    except AttributeError:
        result = list(repeat_values(iterable))
    else:
        result = dict(enumerate(repeat_values(iterable)))
    return result

lst = ['Hi!', 'Hello!']
multiplier = 3
extend_collection(multiplier, lst)
# ['Hi!', 'Hello!', 'Hi!', 'Hello!', 'Hi!', 'Hello!']

Upvotes: 2

StubbyAngel9
StubbyAngel9

Reputation: 96

It's not immediately clear why you might want to do this. If the keys are always consecutive integers then you probably just want a list.

Anyway, here's a snippet:

def dictExtender(multiplier, d):
    return dict(zip(range(multiplier * len(d)), list(d.values()) * multiplier))

Upvotes: 2

Flynsee
Flynsee

Reputation: 596

I don't think you need to use inheritance to achieve that. It's also unclear what the keys should be in the resulting dictionary.

If the keys are always consecutive integers, then why not use a list?

origin = ['Hi', 'Hello']
extended = origin * 3 
extended
>> ['Hi', 'Hello', 'Hi', 'Hello', 'Hi', 'Hello']
extended[4]
>> 'Hi'

If you want to perform a different operation with the keys, then simply:

mult_key = lambda key: [key,key+2,key+4] # just an example, this can be any custom implementation but beware of duplicate keys
dic = {0:'Hi', 1:'Hello'}
extended = { mkey:dic[key] for key in dic for mkey in mult_key(key) }
extended
>> {0:'Hi', 1:'Hello', 2:'Hi', 3:'Hello', 4:'Hi', 5:'Hello'}

Upvotes: 0

Related Questions