Sandy
Sandy

Reputation: 263

How to convert dictionary to default dictionary?

mapfile = {
    1879048192: 0,
    1879048193: 0,
    1879048194: 0,
    1879048195: 0,
    1879048196: 4,
    1879048197: 3,
    1879048198: 2,
    1879048199: 17,
    1879048200: 0,
    1879048201: 1,
    1879048202: 0,
    1879048203: 0,
    1879048204: 4,
    # intentionally missing byte
    1879048206: 2,
    1879048207: 1,
    1879048208: 0 # single byte cannot make up a dword
}

_buf = {}
for x in (x for x in mapfile.keys() if 0==x%4):
    try:
        s = "0x{0:02x}{1:02x}{2:02x}{3:02x}".format(mapfile[x+3], mapfile[x+2],
                                                    mapfile[x+1], mapfile[x+0])
        print "offset ", x, " value ", s
        _buf[x] = int(s, 16)
    except KeyError as e:
        print "bad key ", e

    print "_buf is ", _buf

Since I am using dictionary, I am getting KeyError. Plan is to make dictionary as defaultdict(int) so that in default dictionary it will pad zero when there is KeyError. But I didn't find any solution. How I can convert dictionary to default dictionary?

Upvotes: 14

Views: 18159

Answers (5)

int soumen
int soumen

Reputation: 531

In the question, user wants to convert the below dictionary to a default-dictionary:

mapfile = {
    1879048192: 0,
    1879048193: 0,
    1879048194: 0,
    1879048195: 0,
    1879048196: 4,
    1879048197: 3,
    1879048198: 2,
    1879048199: 17,
    1879048200: 0,
    1879048201: 1,
    1879048202: 0,
    1879048203: 0,
    1879048204: 4,
    # intentionally missing byte
    1879048206: 2,
    1879048207: 1,
    1879048208: 0 # single byte cannot make up a dword
}

API for defaultdict https://docs.python.org/3/library/collections.html#collections.defaultdict

The defaultdict constructor requires two arguments here. A default factory function as the first parameter and the plain dictionary itself. The purpose of the factory function is to return a default value when the dictionary is accessed with an unknown key, without throwing any KeyError.

If we observed the original question, it requires a defaultdict of int, with an assumption that the default value for an unknown key is 0 below code should work as fine:

defaultdict(lambda: 0, mapfile)

Upvotes: 0

martineau
martineau

Reputation: 123463

Although you could convert the dictionary to a defaultdict simply by:

mapfile = collections.defaultdict(int, mapfile)

In your example code it might be better just make it part of the creation process:

mapfile = collections.defaultdict(int, {
    1879048192: 0,
    1879048193: 0,
    1879048194: 0,
    1879048195: 0,
    1879048196: 4,
    1879048197: 3,
    1879048198: 2,
    1879048199: 17,
    1879048200: 0,
    1879048201: 1,
    1879048202: 0,
    1879048203: 0,
    1879048204: 4,
    # intentionally missing byte
    1879048206: 2,
    1879048207: 1,
    1879048208: 0 # single byte cannot make up a dword
})

print(mapfile[1879048205])  # -> 0
print(mapfile['bogus'])  # -> 0

Yet another alternative would be to derive your own class. It wouldn't require much additional code to implement a dictionary-like class that not only supplied values for missing keys like defaultdicts do, but also did a little sanity-checking on them. Here's an example of what I mean — a dict-like class that only accepts missing keys if they're some sort of integer, rather than just about anything like a regular defaultdict:

import numbers

class MyDefaultIntDict(dict):
    default_value = 0
    def __missing__(self, key):
        if not isinstance(key, numbers.Integral):
            raise KeyError('{!r} is an invalid key'.format(key))
        self[key] = self.default_value
        return self.default_value

mapfile = MyDefaultIntDict({
    1879048192: 0,
    1879048193: 0,
    1879048194: 0,
    1879048195: 0,
    1879048196: 4,
    1879048197: 3,
    1879048198: 2,
    1879048199: 17,
    1879048200: 0,
    1879048201: 1,
    1879048202: 0,
    1879048203: 0,
    1879048204: 4,
    # intentionally missing byte
    1879048206: 2,
    1879048207: 1,
    1879048208: 0 # single byte cannot make up a dword
})

print(mapfile[1879048205])  # -> 0
print(mapfile['bogus'])  # -> KeyError: "'bogus' is an invalid key"

Upvotes: 2

itzMEonTV
itzMEonTV

Reputation: 20349

I think, KeyError can be solved here by setting 0 as default value.

In [5]: mydict = {1:4}

In [6]: mydict.get(1, 0)
Out[6]: 4

In [7]: mydict.get(2, 0)
Out[7]: 0

Hope this helps. You can change your code to something like mapfile.get([x+3], 0).

OR

from collections import defaultdict
mydict = {1:4}
mydefaultdict = defaultdict(int, mydict)
>>>mydefaultdict[1]
4
>>>mydefaultdict[2]
0

Upvotes: 5

Vlad
Vlad

Reputation: 18633

You can convert a dictionary to a defaultdict:

>>> a = {1:0, 2:1, 3:0}
>>> from collections import defaultdict
>>> defaultdict(int,a)
defaultdict(<type 'int'>, {1: 0, 2: 1, 3: 0})

Upvotes: 24

DeepSpace
DeepSpace

Reputation: 81604

Instead of re-creating the dictionary, you can use get(key, default). key is the key that you want to retrieve and default is the value to be returned if the key isn't in the dictionary:

my_dict = { }
print my_dict.get('non_existent_key', 0)
>> 0

Upvotes: 11

Related Questions