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>

<h1>Using a list comprehension</h1>

<p>Since you are searching for an alternative not using a for loop here is an implementation using <a href="https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions" rel="nofollow">list comprehensions</a>, which results in a two liner. I am not sure though that this is more intuitive than a for loop:</p>

<pre><code>output = {}
[output.setdefault(item["time"],{}).update({key: value}) 
 for key, value in item.items()     
 if key != "time" 
 for item in (listA + listB)]
</code></pre>

<p>To me this is just a more convoluted way of for loops...
Documentation for <a href="https://docs.python.org/3/library/stdtypes.html#dict.setdefault" rel="nofollow">setdefault</a>.</p>

<h1>Using classic for loops</h1>

<p>Use <code>listA</code> and <code>listB</code> as given in your example:</p>

<pre><code>combined = listA + listB

merged = {}
for item in combined:
    time = item["time"]
    # setdefault only acts if the key is not found, initiate a dict then
    merged.setdefault(time, {})
    for key, value in item.items():
        if key != "time":
            merged[time].update({key: value})

print merged
</code></pre>

<p>Output:</p>

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

python list dictionary