How to add the missing element to second list by comparing two lists

Viewed 980

I have two lists which contain datewise data and want to add a missing data of a date in list2 by comparing with list1

Lists like below

 list1=['2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04', '2019-06-05']
 list2=[['2019-06-01','3'], ['2019-06-02','0'],['2019-06-04','1'], ['2019-06-05', '4']]

Here in list2 doesn't contain data for 2019-06-03, so want to add that missing data of that date to list2 with empty values and final values of list2 contain like below

list2=[['2019-06-01','3'], ['2019-06-02','0'],['2019-06-03','']['2019-06-04','1'], ['2019-06-05', '4']]

Below is the code I'm trying with to get missing values to another list

 for a, b in itertools.izip_longest(list1,list2):
     if a!=b[0]:
         print a

which prints like below

  2019-06-03
  2019-06-04
  2019-06-05

Can somebody guide me here

9 Answers

This is one approach using itertools.chain and set

Ex:

from itertools import chain

list1=['2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04', '2019-06-05']
list2=[['2019-06-01','3'], ['2019-06-02','0'],['2019-06-04','1'], ['2019-06-05', '4']]

check_val = set(chain.from_iterable(list2))

for i in list1:
    if i not in check_val:
        list2.append([i, ""])
print(list2)
print(sorted(list2, key=lambda x: x[0]))

Output:

[['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-04', '1'], ['2019-06-05', '4'], ['2019-06-03', '']]
[['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-03', ''], ['2019-06-04', '1'], ['2019-06-05', '4']]
dates_in_list2 = [x[0] for x in list2]
missing_data = [[x, ''] for x in list1 if x not in dates_in_list2]
list2.extend(missing_data)

You could use sets to and find the set.difference and add a new sublist with from the result:

list2 += [list(set(list1).difference([i[0] for i in list2])) + ['']]

print(list2)

[['2019-06-01', '3'],
 ['2019-06-02', '0'],
 ['2019-06-04', '1'],
 ['2019-06-05', '4'],
 ['2019-06-03', '']]

Why not a list comprehension containing a generator expression:

print([next((x for x in list2 if v in x), [v, '']) for i, v in enumerate(list1)])

Output:

[['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-03', ''], ['2019-06-04', '1'], ['2019-06-05', '4']]

It keeps the order correct automatically.

you can use set difference to find the missing dates, then add them to list2 (and sort it by date...).

try this:

list1 = ['2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04', '2019-06-05']
list2 = [['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-04', '1'], ['2019-06-05', '4']]

set1 = {*list1}
set2 = {t[0] for t in list2}

diff = set1 - set2

for date in diff:
    list2.append([date, ''])

list2.sort(key=lambda t: t[0])
print(list2)

Output:

[['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-03', ''], ['2019-06-04', '1'], ['2019-06-05', '4']]

What you have to do is for each element in list1 iterate over list2 and see if there is a matching element. Considering that your lists are small this shouldn't be a performance issue. If you know that your lists are sorted then you can make some optimizations but that might be an overkill for now.

Another set difference within a single pipeline:

list2.extend([i, ''] for i in set(list1) - set(d[0] for d in list2))
list2.sort()
print(list2)

The output:

[['2019-06-01', '3'], ['2019-06-02', '0'], ['2019-06-03', ''], ['2019-06-04', '1'], ['2019-06-05', '4']]

I will use numpy setdiff1d function then append each item to list2.

import numpy as np
list1=['2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04', '2019-06-05']
list2=[['2019-06-01','3'], ['2019-06-02','0'],['2019-06-04','1'], ['2019-06-05', '4']]
diff=np.setdiff1d(list1, [b[0] for b in list2])
for i in diff:
    list2.append([i,''])
list2.sort()
Result:
[['2019-06-01', '3'],
 ['2019-06-02', '0'],
 ['2019-06-04', '1'],
 ['2019-06-05', '4'],
 ['2019-06-03', '']]

You could do it with a dictionary constructor. Because the constructor overrides values of duplicate keys, you can provide it with the two lists and let it prioritize list2 over list1 (with its default value):

result = sorted(dict((a[0],a[1:] or ["x"]) for a in list1+list2).values(),key=tuple)

Note: you only have to use sorted() if you need to preserve the order

If list1 always contains all possible dates, you could use a dictionary of list2 data as an override over default values:

result = [[d,v.get(d,"x")] for v in [dict(list2)] for d in list1]

Note: this preserves the order and is faster than the other approach but requires list1's dates to be a superset of list2's

Related