Andrew Leland
Andrew Leland

Reputation: 11

Are there any strategies around editing dictionaries nested in shared dictionaries?

I'm trying to edit a dictionary inside a shared dictionary in separate processes but they're immutable. Are there any techniques that I might be missing on how to get around this?

Here's an example

import multiprocessing

def main():
    manager = multiprocessing.Manager()
    dictionary = manager.dict()

    dictionary["jim"] = {'x': 1, 'y': 2, 'z' : 3}

    print(dictionary['jim'])

    dictionary['jim']['x'] += 1

    print(dictionary['jim'])

if __name__ == '__main__':
    main()

Upvotes: 1

Views: 56

Answers (2)

blhsing
blhsing

Reputation: 107015

You can nest a shared dict in the shared dict:

dictionary["jim"] = manager.dict({'x': 1, 'y': 2, 'z' : 3})

Demo: https://ideone.com/5jS2SK

Excerpt from the documentation:

Shared objects are capable of being nested. For example, a shared container object such as a shared list can contain other shared objects which will all be managed and synchronized by the SyncManager.

Upvotes: 0

Mark Tolonen
Mark Tolonen

Reputation: 178031

dictionary is a DictProxy object. Getting an item from that proxy such as dictionary['jim'] returns a copy of the proxied dictionary value; in this case, another dictionary. Then, dictionary['jim']['x'] modifies that copy and not the shared process memory containing the actual dictionary contents.

To fix, extract a key's value from the ProxyDict, modify it, and assign it back to the same key:

import multiprocessing

def main():
    manager = multiprocessing.Manager()
    dictionary = manager.dict()
    dictionary["jim"] = {'x': 1, 'y': 2, 'z' : 3}
    print(dictionary['jim'])
    d = dictionary['jim']  # extract the value from the DictProxy
    d['x'] += 1            # modify it
    dictionary['jim'] = d  # assign it back
    print(dictionary['jim'])

if __name__ == '__main__':
    main()

Output:

{'x': 1, 'y': 2, 'z': 3}
{'x': 2, 'y': 2, 'z': 3}

Upvotes: 1

Related Questions