0

I want to append value to an existing dictionary. Here is my code:

tmp_result = [{'M': 8}, {'N': 16},]
cross_configs = [({'device': 'cpu'},), ({'device': 'cuda'},)]

import copy
generated_configs = []
for config in cross_configs:
    for value in config:
            new_value = copy.deepcopy(tmp_result)
            new_value.append(value)
            generated_configs.append(new_value)

print (generated_configs)

Output: 
[[{'M': 8}, {'N': 16}, {'device': 'cpu'}], [{'M': 8}, {'N': 16}, {'device': 'cuda'}]]

I don't like the inner loop which does deepcopy and append. What is a pythonic way to do that?

6
  • 2
    Why the lists of single pair dictionaries? Commented Jul 25, 2019 at 18:34
  • This does not "append" values to dictionaries; this appends additional single-entry dictionaries to a list. Your result is two lists of three independent dictionaries each. What problem are you trying to solve with this data structure? Commented Jul 25, 2019 at 18:37
  • probably you meant to name the title as "Merge 2 lists" Commented Jul 25, 2019 at 18:39
  • I don't see how you're appending to a dictionary. You seem to be dealing with lists of lists who elements just happen to be single-key dictionaries, or sets/tuples of one dictionary each. Are you ultimately trying to take [a,b,c] and [(c),(d)] and return [ [a,b,c], [a,b,d] ]? Commented Jul 25, 2019 at 18:39
  • 1
    That does not really explain why someone thought it might be a good idea to pack a single entry dict into a list into a list. Maybe suggesting a refactoring of the interface is worthwhile as it can help avoid poor performance and hard to maintain source. Furthermore it is not really clear why you would need a deep copy. Are the lists altered afterwards? Commented Jul 25, 2019 at 18:49

2 Answers 2

1

You could do a list-comprehension:

[tmp_result + list(x) for x in cross_configs]

Example:

tmp_result = [{'M': 8}, {'N': 16},]
cross_configs = [({'device': 'cpu'},), ({'device': 'cuda'},)]

print([tmp_result + list(x) for x in cross_configs])
# [[{'M': 8}, {'N': 16}, {'device': 'cpu'}], [{'M': 8}, {'N': 16}, {'device': 'cuda'}]]
Sign up to request clarification or add additional context in comments.

Comments

0

A nested list comprehension will suffice; the explicit call to dict is sufficient to avoid the need for deepcopy given the example shown.

generated_configs = [[dict(y) for y in tmp_result + list(x)] for x in cross_configs]

If you object to tmp_result + list(x), use itertools.chain instead.

from itertools import chain
generated_configs = [[dict(y) for y in chain(tmp_result, x)] for x in cross_configs]

3 Comments

Couldn't nested list-comprehension be avoided as in my answer?
list(x) will only make a shallow copy of the tuple, meaning each sublist will share a reference to the same device dict. The call to dict ensures that each dict in the result is distinct. (It's not equivalent to a deep copy of each list, in the event that the dicts themselves contain references to mutable objects, but it is sufficient for the dicts shown in the question.)
It's almost certainly not an issue for the example show, since the two dict literals will create separate objects. But consider something like d1 = {'device': 'cpu'}; d2 = {'device': 'cuda'}; cross_configs = [(d1,), (d1,), (d2,), (d1,), (d2,)].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.