Поєднання двох списків та видалення дублікатів, без вилучення дублікатів у вихідному списку


115

У мене є два списки, які мені потрібно поєднувати там, де у другому списку проігноровані будь-які дублікати першого списку. .. Трохи важко пояснити, тому дозвольте мені показати приклад того, як виглядає код, і чого я хочу в результаті.

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: Так, я ще не повністю вирішив, як мені це вдається вирішити. Це те, про що я думав, але залишив поза
увагою

Відповіді:


168

Вам потрібно додати до першого списку ті елементи другого списку, яких немає у першому - набори - це найпростіший спосіб визначити, які вони елементи, наприклад:

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

2
Або це, якщо вам це потрібно, відсортовано: надрукувати 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
статичний

66
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

Ця методика зберігає порядок атрибутів у списку, що не так set. 👍
Subhash Bhushan

29

Ви можете використовувати набори:

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]


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


0

Це може допомогти

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

Функція об'єднання об'єднує другий список у перший, з дублюючим елементом a, якщо він вже є. Аналогічно встановленому оператору союзу. Ця функція не змінюється b. Якщо a = [1,2,3] b = [2,3,4]. Після об'єднання (a, b) складає a = [1,2,3,4] і b = [2,3,4]


0

Спираючись на рецепт :

результуючий список = список (встановити (). союз (перший_ список, другий список))


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.