1

I have this 2 lists of list:

list1= [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]

list2= [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

And I desire to output this:

desiredlist =[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0], ['user4', 288, 'Feb 2017', 60, 10]]

For that I have this function:

def mergesafirmacheta(list1,list2):
    desiredlist = []
    for id, n1, dates, n2, n3 in list1:
        counter = 0
        for list_2 in list2:
            if n1 == list_2[1]:
                desiredlist.append(list_2[:3] + [n2, list_2[4]])
            else:
                   counter += 1
                   if counter == len(list2):
                       desiredlist.append([id, n1, dates, n2, 0])
    print (desiredlist)

But this will output just this:

desiredlist =[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0]]

^^ user4 is missing (check my desired output), I can see why from my function, I try to add this after my first is statement:

elif list_2[1] != n1:
    desiredlist.append(list_2)

But this won't work, this are the rules to compute the desired list:

When list2[1] == list1[1] (example 186 == 186) append to my desiredlist list2[0], list2[1], list2[2], list1[3], list2[4], if you have a list1[1] that is not in list2 lists change append to desiredlist list1[0], list1[1], list1[2], list1[3], 0, and if a list2[1] that is not in list1 lists append to desiredlist list2[0], list2[1], list2[2], list2[3], list2[4]. This is a bit hard to fallow but I think is much easier to check for my desired output and what I actually output right now.

4
  • 3
    So all the "values" should originate from the second list? It is not really clear to me how you merge the input. Commented Sep 22, 2017 at 10:52
  • Why won't you use a dictionary instead? Commented Sep 22, 2017 at 10:55
  • From both, in my desired output there is user3 (original from list1) and user4(original from list2) Commented Sep 22, 2017 at 10:55
  • It’s very unclear to me when a value will be carried over from one list or another. For example, for user 1, the 550 is taken from the first and the 740 is taken from the second list. But for user 2, the 1000 of the second list wins over the 3579 from the first. Why?! What is the rule? Commented Sep 22, 2017 at 11:40

3 Answers 3

1

I managed to do what you intended by changing your format. I convert all your sublists into dict with the key user.

Because it easier to merge dict and the order of user in your sublists doesn't matter.

The last steps is to iterate over the merged dict of list1 and list2 and do your special operation. As I understood, is to take the before last number of list1 and merge it with list2. Then you recreate your desired sublist.

from itertools import chain
from collections import defaultdict

list1 = [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]
list2 = [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

# Transform list to dict with key as 'userN'
def to_dict(lst): return {x[0]: x[1:] for x in lst} 

# Now create a dict that combined list of user1..N+1
tmp_dict = defaultdict(list)
for k, v in chain(to_dict(list1).items(), to_dict(list2).items()):
  tmp_dict[k].append(v)

desired_output = []
for k, v in tmp_dict.items():
  if len(v) == 2:
    v[1][-2] = v[0][-2] # Take the before last of list1 to remplace with before last one of list2
    desired_output.append([k] + v[1])
  else:
    desired_output.append([k] + v[0])

print(desired_output)

Output:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 60], ['user4', 288, 'Feb 2017', 60, 10]]

EDIT

It seems I make a mistake and your list1 have to check all the content of list2, in that case you should make a dict of list2 first and apply your specific condition after. eg:

from itertools import chain

list1 = [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]
list2 = [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

# Transform list to dict with key as 'userN'
def to_dict(lst): return {x[0]: x[1:] for x in lst} 

# First, transfrom list2 to dict
list2_dict = {}
for k, v in to_dict(list2).items():
  list2_dict[k] = v

# Then iterate on list1 to compare
desired_output = []
for k, v in to_dict(list1).items():
  if k in list2_dict: # key of list1 exists in list2
    list2_dict[k][-2] = v[-2] # replace value
    desired_output.append([k] + list2_dict[k]) # Then add list2
    list2_dict.pop(k) # And remove it from old dict
  else: # list1 does not exists in list2
    v[-1] = 0 # Set last element to zero
    desired_output.append([k] + v)

for k, v in list2_dict.items(): # Now add elements present only in list2
  desired_output.append([k] + v)

print(desired_output)

output:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 0], ['user4', 288, 'Feb 2017', 60, 10]]

Note: we can get rid of defaultdict since the same key is not being to be added twice.

Sign up to request clarification or add additional context in comments.

4 Comments

Same thing here ['user3', 281, 'Mai 2017', 10, 60] should be: ['user3', 281, 'Mai 2017', 10, 0], like I posted in my desired output. ( if you have a list1[1] that is not in list2 lists append to desiredlist list1[0], list1[1], list1[2], list1[3], 0)
@TatuBogdan, Oh wow, this is a tricky condition. Well in that case you option will be to first transform you second list in a dict and THEN try with the second one, you can add special check there after that.
@TatuBogdan please check my edit, I tried to include your remark in your "tricky" condition
Works, thank you, I will study the code and try to understand it more into detail. Nice one, you saved me!
1

Use this code :

list1= [['user1', 186, 'Feb 2017, Apr 2017', 550, 555], ['user2', 282, 'Mai 2017', 0, 3579], ['user3', 281, 'Mai 2017', 10, 60]]

list2= [['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 0, 740],['user2', 282, 'Feb 2017', 0, 1000], ['user4', 288, 'Feb 2017', 60, 10]]

final_list = []
for l1_data, l2_data in zip(list1, list2):
    if l1_data[0] == l2_data[0]:
        for index, elem in enumerate(l2_data):
            if index+1 <= len(l1_data):
                if not elem and l1_data[index]:
                    l2_data[index] = l1_data[index]                    
    else: final_list.append(l1_data)
    final_list.append(l2_data)
print final_list

Ouptut:

[['user1', 186, 'Feb 2017, Mar 2017, Mai 2017', 550, 740], ['user2', 282, 'Feb 2017', 0, 1000], ['user3', 281, 'Mai 2017', 10, 60], ['user4', 288, 'Feb 2017', 60, 10]]

4 Comments

I was checking your output, only problem is in this list: ['user3', 281, 'Mai 2017', 10, 60] when you don't have a match I would like with 0 like this: ['user3', 281, 'Mai 2017', 10, 0] (I posted in my desired output.
if you have a list1[1] that is not in list2 lists append to desiredlist list1[0], list1[1], list1[2], list1[3], 0
But there is no any list containing user3 in list2. Thats why I added those as it is in the final list.
I see, it's on list1, it isn't possible when you loop to also check if it's in list1 and not in list2 and then make that index[4] to 0?
0

you can iterate through the distinct second element of both list combined:

for n in set([item[1] for item in list1+list2]):

then you can decide to add to your desired list by looking up n in both list

Comments

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.