175

I have two lists that i need to combine where the second list has any duplicates of the first list ignored. .. A bit hard to explain, so let me show an example of what the code looks like, and what i want as a result.

first_list = [1, 2, 2, 5]

second_list = [2, 5, 7, 9]

# The result of combining the two lists should result in this list:
resulting_list = [1, 2, 2, 5, 7, 9]

You'll notice that the result has the first list, including its two "2" values, but the fact that second_list also has an additional 2 and 5 value is not added to the first list.

Normally for something like this i would use sets, but a set on first_list would purge the duplicate values it already has. So i'm simply wondering what the best/fastest way to achieve this desired combination.

Thanks.

Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
Lee Olayvar
  • 3,660
  • 6
  • 30
  • 36

12 Answers12

236

You need to append to the first list those elements of the second list that aren't in the first - sets are the easiest way of determining which elements they are, like this:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

in_first = set(first_list)
in_second = set(second_list)

in_second_but_not_in_first = in_second - in_first

result = first_list + list(in_second_but_not_in_first)
print(result)  # Prints [1, 2, 2, 5, 9, 7]

Or if you prefer one-liners 8-)

print(first_list + list(set(second_list) - set(first_list)))
phoenix
  • 7,988
  • 6
  • 39
  • 45
RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • 2
    Or this if you need it sorted: print first_list + sorted(set(second_list) - set(first_list)) – hughdbrown Aug 23 '09 at 20:10
  • 3
    List(set(first_list)|set(second_list)) #| is set intersection see http://stackoverflow.com/questions/4674013/how-to-take-two-lists-and-combine-them-excluding-any-duplicates – staticd Sep 30 '13 at 15:43
  • 1
    @staticd: Yes, but that gives the wrong answer. There's only one `2` in your result, when there should be two of them. – RichieHindle Sep 30 '13 at 16:04
  • oops. You're right. Totally missed that the first list *was* allowed duplicates. :P – staticd Oct 03 '13 at 04:34
  • Note: this solution doesn't preserve the sequence. For that feature, go to https://stackoverflow.com/a/1319355/2470337 . – Dr_Zaszuś Jul 25 '23 at 07:45
125
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
74

You can use sets:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

resultList= list(set(first_list) | set(second_list))

print(resultList)
# Results in : resultList = [1,2,5,7,9]
Davide Pizzolato
  • 679
  • 8
  • 25
29
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
14

You can bring this down to one single line of code if you use numpy:

a = [1,2,3,4,5,6,7]
b = [2,4,7,8,9,10,11,12]

sorted(np.unique(a+b))

>>> [1,2,3,4,5,6,7,8,9,10,11,12]
mosegui
  • 664
  • 6
  • 15
12

Simplest to me is:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

merged_list = list(set(first_list+second_list))
print(merged_list)

#prints [1, 2, 5, 7, 9]
Rafiq
  • 1,380
  • 4
  • 16
  • 31
  • 1
    That's a great solution, but keep in mind that it won't work if we try to make array of dictionaries a set e.g. (will raise `TypeError: unhashable type: 'dict'`) – Evgenia Karunus Jun 15 '18 at 07:47
8
resulting_list = first_list + [i for i in second_list if i not in first_list]
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
4

You can also combine RichieHindle's and Ned Batchelder's responses for an average-case O(m+n) algorithm that preserves order:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

fs = set(first_list)
resulting_list = first_list + [x for x in second_list if x not in fs]

assert(resulting_list == [1, 2, 2, 5, 7, 9])

Note that x in s has a worst-case complexity of O(m), so the worst-case complexity of this code is still O(m*n).

Community
  • 1
  • 1
z0r
  • 8,185
  • 4
  • 64
  • 83
2

you can use dict.fromkeys to return a list with no duplicates:

def mergeTwoListNoDuplicates(list1, list2):
    """
    Merges two lists together without duplicates
    :param list1:
    :param list2:
    :return:
    """
    merged_list = list1 + list2
    merged_list = list(dict.fromkeys(merged_list))
    return merged_list
B. Mohammad
  • 2,152
  • 1
  • 13
  • 28
1

Based on the recipe :

resulting_list = list(set().union(first_list, second_list))

Alon
  • 761
  • 6
  • 7
0

This might help

def union(a,b):
    for e in b:
        if e not in a:
            a.append(e)

The union function merges the second list into first, with out duplicating an element of a, if it's already in a. Similar to set union operator. This function does not change b. If a=[1,2,3] b=[2,3,4]. After union(a,b) makes a=[1,2,3,4] and b=[2,3,4]

athspk
  • 6,722
  • 7
  • 37
  • 51
VeilEclipse
  • 2,766
  • 9
  • 35
  • 53
-1
    first_list = [1, 2, 2, 5]
    second_list = [2, 5, 7, 9]

    newList=[]
    for i in first_list:
        newList.append(i)
    for z in second_list:
        if z not in newList:
            newList.append(z)
    newList.sort()
    print newList

[1, 2, 2, 5, 7, 9]