-1

I am trying to combine 2 lists of pairs.

List 1:

dyndns = [('user1', 'dyndns1'), ('user2', 'dyddns2'), ('user3', 'dyndns3'), ('user4', 'dyddns4')]

List 2:

ip = [('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user4', '1.1.1.4')]

I want to join List 1 to List 2, but only want to add the item from List 1 if it does not exist in List 2.
As you can see List 1 has user1, user2, user3 and user4, but List 2 only has user1, user2 and user4
The combined list has all users from List 2 as well as the extra users in List 1

Combined List:

combined = [('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user3', 'dyndns3'), ('user4', '1.1.1.4')]
Kevin Crick
  • 187
  • 1
  • 2
  • 8

5 Answers5

4
ip_dict = dict(ip)
print([(user, ip_dict.get(user, dns)) for user, dns in dyndns])

This outputs:

[('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user3', 'dyndns3'), ('user4', '1.1.1.4')]
Luca Cappelletti
  • 2,485
  • 20
  • 35
blhsing
  • 91,368
  • 6
  • 71
  • 106
2

A lengthy discussion of de-duplicating while preserving sort order can be found here. Applied to this case de-duplicating entries is trivially simple if you convert to a dictionary:

from collections import OrderedDict
print(list(OrderedDict(dyndns + ip).items()))

Which outputs your desired result:

[('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user3', 'dyndns3'), ('user4', '1.1.1.4')]

For more context, your lists are already correctly formatted to be sent to the dict (or OrderedDict) constructor, as they are lists of key, value tuples.

What we are doing is to build an OrderedDict from dyndns and ip lists combined which will ensure the keys are in the order defined in the dyndns list, but any values from ip will over-ride values defined in dyndns (because later values override earlier values). We then convert back to a list of tuples by calling items and casting to a list.

If order is not important (or if you are in python 3.6+), this can be simplified to:

print(list(dict(dyndns + ip).items()))
Matthew Story
  • 3,573
  • 15
  • 26
1

We get list of keys or users from ip (list 2) and iterate on another list to check if the key is present in list 2 already, if not present add to the list.

ip = [('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user4', '1.1.1.4')]
dyndns = [('user1', 'dyndns1'), ('user2', 'dyddns2'), ('user3', 'dyndns3'), ('user4', 'dyddns4')]
ip_keys = list(map (lambda x:x[0], ip))
for i in dyndns:
    if (not i[0] in ip_keys):
        ip.append(i)
Umang Gupta
  • 15,022
  • 6
  • 48
  • 66
0

The following code can be used to achieve the output. It used Python's sorted() function based on its key keyword argument.

def get_combined_users(list1, list2):
    usernames = set()
    combined = []

    for user in sorted(list2 + list1, key=lambda user: user[0]): # Do not use => list1 + list2
        if not user[0] in usernames:
            usernames.add(user[0])
            combined.append(user)

    return combined

if __name__ == "__main__":
    dyndns = [('user1', 'dyndns1'), ('user2', 'dyddns2'), ('user3', 'dyndns3'), ('user4', 'dyddns4')]
    ip = [('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user4', '1.1.1.4')]

    combined = get_combined_users(dyndns, ip)
    print(combined)

Output

[('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user3', 'dyndns3'), ('user4', '1.1.1.4')]
hygull
  • 8,464
  • 2
  • 43
  • 52
0

Try this one:-

def get(l1,l2):
    la1 = [i[0] for i in l1]
    la2 = [i[0] for i in l2]
    for i in la1:
        if i not in la2:
            l2.append(l1[la1.index(i)])
    return l1


print(get([('user1', 'dyndns1'), ('user2', 'dyddns2'), ('user3', 'dyndns3'), 
('user4', 'dyddns4')],[('user1', '1.1.1.1'), ('user2', '1.1.1.2'), ('user4', 
'1.1.1.4')]
))

#output:-- [('user1', 'dyndns1'), ('user2', 'dyddns2'), ('user3', 'dyndns3'), ('user4', 'dyddns4')]
Vicrobot
  • 3,795
  • 1
  • 17
  • 31