Merge two lists and create a new dictionary
<p>I could not find a good way to do this. Suppose I have two lists (the lists have objects with given attributes). I need to create a new dictionary/list with merged atttributes.</p>

<pre><code>listA = [
  {
    "alpha": "some value",
    "time": "datetime",
  },
  ...
]

listB = [
  {
    "beta": "some val",
    "gamma": "some val",
    "time": "datetime"
  },
  ...
]
</code></pre>

<p>The result should be as follows (it should be merged based on "time" attribute)</p>

<pre><code>result = {
  "datetime": {
    "alpha": "some value",
    "beta": "some val",
    "gamma": "some val"
  },
  ...
}
</code></pre>

<p>How do I do this in a python way?</p>

<p>For example,</p>

<pre><code>listA = [
  {
    "time": "Jan 1",
    "alpha": "one"
  },
  {
    "time": "Jan 3",
    "alpha": "three"
  }
]

listB = [
  {
    "beta": "one-one",
    "gamma": "one-two",
    "time": "Jan 1"
  },
  {
    "beta": "two-one",
    "gamma": "two-two",
    "time": "Jan 2"
  },
]

result = {
  "Jan 1": {
    "alpha": "one",
    "beta": "one-one",
    "gamma": "one-two",
  },
  "Jan 2": {
    "beta": "two-one",
    "gamma": "two-two",
  },
  "Jan 3": {
    "alpha": "three"
  }
}
</code></pre>

<p>Another answer, that's perhaps cleaner in that it avoids conditional tests in favour of dict methods and uses only one level of indentation:</p>

<pre><code>d={}

for e in listA:
    t = e["time"]
    d.setdefault(t, {}).update(**e)

for e in listB:
    t = e["time"]
    d.setdefault(t, {}).update(**e)

# get rid of "time" keys, if important to do so

for e in d.values():
    del e["time"]
</code></pre>

<p><code>d.setdefault(t, {})</code> creates <code>d[t]</code> as an empty dict if the key <code>t</code> is not yet present in <code>d</code>, and returns <code>d[t]</code>. Then<code>.update(**e)</code> updates the returned dict to contain all keys and values in <code>e</code> (replacing current values if they exist, which may be a bug or a feature - the example did not have any overlaps or say what should happen if there are overlaps)</p>

python list dictionary