Объединение двух списков и удаление дубликатов без удаления дубликатов в исходном списке

117

У меня есть два списка, которые мне нужно объединить, где во втором списке игнорируются дубликаты первого списка. .. Сложно объяснить, поэтому позвольте мне показать пример того, как выглядит код и чего я хочу в результате.

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]

Вы заметите, что результат имеет первый список, включая два его значения «2», но тот факт, что second_list также имеет дополнительные значения 2 и 5, не добавляется к первому списку.

Обычно для чего-то вроде этого я бы использовал наборы, но набор в first_list удалял бы повторяющиеся значения, которые у него уже есть. Так что мне просто интересно, какой лучший / самый быстрый способ достичь желаемой комбинации.

Спасибо.

Ли Олайвар
источник
3
Что делать, если есть три двойки second_list?
balpha
@balpha: Да, я еще не до конца решил, как мне с этим справиться. Это то, о чем я думал, но
упустил из виду

Ответы:

169

Вам нужно добавить в первый список те элементы второго списка, которых нет в первом - наборы - это самый простой способ определить, какими элементами они являются, например:

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]

Или, если вы предпочитаете однострочники 8-)

print(first_list + list(set(second_list) - set(first_list)))
RichieHindle
источник
2
Или это, если вам нужно отсортировать: print first_list + sorted (set (second_list) - set (first_list))
hughdbrown
2
Список (set (first_list) | set (second_list)) # | установлено пересечение, см. stackoverflow.com/questions/4674013/…
staticd
1
@staticd: Да, но это неправильный ответ. В 2вашем результате только один , а их должно быть два.
RichieHindle
упс. Ты прав. Совершенно упустил, что в первом списке были разрешены дубликаты. : P
статично 03
67
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)
Нед Батчелдер
источник
7
Наконец-то ответ, который не включает разбиение на наборы! Престижность.
SuperFamousGuy
4
на самом деле это O (n * m), но это может быть удобно, когда у вас есть список нехешируемых вещей и производительность не является проблемой
alcuadrado
1
Что я не хочу дублировать ни с первого, ни со второго?
Dejell 05
Этот метод сохраняет порядок атрибутов в списке, чего нельзя сказать о set. 👍
Субхаш Бхушан
31

Можно использовать наборы:

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]
Катираван Умайдурай
источник
Да, спасибо, я понял. Это будет работать нормально. resultList = first_list + list (set (second_list) -set (first_list))
Катираван Умайдурай
9

Вы можете свести это к одной строке кода, если используете 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
источник
7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )
Пол Руб
источник
5
resulting_list = first_list + [i for i in second_list if i not in first_list]
Дэниел Розман
источник
1
setify first_list, и все готово
u0b34a0f6ae
Полученный список не будет отсортирован.
avakar
1
Что, если я вообще не хочу, чтобы в каком-либо списке были дубликаты? таким образом, если в одном списке есть дубликаты, они вернутся
Dejell
5

Самым простым для меня является:

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]
Рафик
источник
1
Это отличное решение, но имейте в виду, что оно не сработает, если мы попытаемся сделать массив словарей набором, например (поднимется TypeError: unhashable type: 'dict')
lakesare
2

Вы также можете комбинировать ответы Ричи Хиндла и Неда Бэтчелдера для алгоритма среднего случая O (m + n) , который сохраняет порядок:

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])

Обратите внимание, что x in sего сложность в наихудшем случае равна O (m) , поэтому сложность этого кода в наихудшем случае по-прежнему составляет O (m * n) .

z0r
источник
0

Это может помочь

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

Функция union объединяет второй список с первым без дублирования элемента a, если он уже находится в. Аналогично оператору объединения множества. Эта функция не меняется b. Если a = [1,2,3] b = [2,3,4]. После объединения (a, b) получается a = [1,2,3,4] и b = [2,3,4]

ВуальЗатмение
источник
-2
    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]

пользователь4846254
источник