Anuj TBE
Anuj TBE

Reputation: 9800

Python join two lists with first index in common

I have two python lists with the following data

list1 = [[datetime.date(2019, 12, 11), 4], [datetime.date(2019, 12, 14), 3]]
list2 = [[datetime.date(2019, 12, 14), 2], [datetime.date(2019, 12, 16), 9]]

I have to combine both list with first index ie., datetime.date field to be common. Also, if first index does not match for the both, set the value to.

Also if any of the list is blank, set the corresponding position to 0.

The resultant will be

list_new = [
   [datetime.date(2019, 12, 11), 4, 0],
   [datetime.date(2019, 12, 14), 3, 2],
   [datetime.date(2019, 12, 16), 0, 9]
]

I tried using zip like

new_list = [a + [b[1]] for (a, b) in zip(list1, list2)]

But this does not seems to be working.

Upvotes: 0

Views: 1360

Answers (4)

Alexander Pushkarev
Alexander Pushkarev

Reputation: 1145

Simple (non-optimal) one-liner:

[[element, dict(list1).get(element, 0), dict(list2).get(element, 0)] for element in set([l[0] for l in list1 + list2])]

Explanation:

  1. Get a set of unique first elements from the list:
>>> s = set([l[0] for l in list1 + list2])
>>> s
set([datetime.date(2019, 12, 11), datetime.date(2019, 12, 14), datetime.date(2019, 12, 16)])
  1. Convert list of two elements to dict:
>>> d1 = dict(list1)
>>> d1
{datetime.date(2019, 12, 11): 4, datetime.date(2019, 12, 14): 3}
>>> d2 = dict(list2)
>>> d2
{datetime.date(2019, 12, 14): 2, datetime.date(2019, 12, 16): 9}

  1. Finally, form the resulting list:
>>> [[element] + [d1.get(element, 0)] + [d2.get(element, 0)] for element in s]
[[datetime.date(2019, 12, 11), 4, 0], [datetime.date(2019, 12, 14), 3, 2], [datetime.date(2019, 12, 16), 0, 9]]

Upvotes: 2

dishant makwana
dishant makwana

Reputation: 1079

  1. Convert the two list of lists to dicts:

    dict1 = dict(list1) dict2 = dict(list2)

  2. Form the new list as:

    new_list = [[a,b,dict2.get(a,0)] for a,b in dict1.iteritems()] + [[a,0,b] for a,b in dict2.iteritems() if a not in dict1]

Upvotes: 1

Andrej Kesely
Andrej Kesely

Reputation: 195543

This merge list1 and list2 using heapq.merge (assuming the dates are sorted in each list and in each list there aren't duplicate dates):

import datetime
from heapq import merge
from pprint import pprint

list1 = [[datetime.date(2019, 12, 11), 4], [datetime.date(2019, 12, 14), 3]]
list2 = [[datetime.date(2019, 12, 14), 2], [datetime.date(2019, 12, 16), 9]]

i1 = ((1, v) for v in list1)
i2 = ((2, v) for v in list2)

d = {}
for v in merge(i1, i2, key=lambda k: k[1]):
    d.setdefault(v[1][0], {})[v[0]] = v[1][1]

out = []
for k, v in d.items():
    out.append((k, *[v.get(i, 0) for i in range(1, 3)]))

pprint(out)

Print:

[(datetime.date(2019, 12, 11), 4, 0),
 (datetime.date(2019, 12, 14), 3, 2),
 (datetime.date(2019, 12, 16), 0, 9)]

Upvotes: 1

MarshallCharles
MarshallCharles

Reputation: 41

Can you be more clear about what you're trying to do?

As I understand, you want to make a new nested list, where each item in that list is the combination of items from the input lists which have the same datetime value. What do the other positions indicate?

In your example:

list_new = [
   [datetime.date(2019, 12, 11), 4, 0],
   [datetime.date(2019, 12, 14), 3, 2],
   [datetime.date(2019, 12, 16), 0, 9]
]

What do the 4,0 3,2 0,9 correspond to in these entries?

Upvotes: 0

Related Questions