Як з'єднати два списки в Python?
Приклад:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
Очікуваний результат:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
[1,2,5] and [2,4,5,6]
? Ви хочете, щоб дублікати були включені, виключені чи не байдуже?
Як з'єднати два списки в Python?
Приклад:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
Очікуваний результат:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
[1,2,5] and [2,4,5,6]
? Ви хочете, щоб дублікати були включені, виключені чи не байдуже?
Відповіді:
Ви можете використовувати +
оператор, щоб комбінувати їх:
listone = [1,2,3]
listtwo = [4,5,6]
joinedlist = listone + listtwo
Вихід:
>>> joinedlist
[1,2,3,4,5,6]
listone += listtwo
результати вlistone == [1, 2, 3, 4, 5, 6]
list3 = listone
listone+=listtwo
чи змінюється також list3?
Можливо також створити генератор, який просто повторює елементи в обох списках, використовуючи itertools.chain()
. Це дозволяє ланцюжка списків (або будь-яких ітерабельних) разом для обробки без копіювання елементів у новий список:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
chain
знаходиться на більш повільній стороні (але не набагато) для двох списків, але це найшвидше рішення для зв'язання декількох списків (n >> 2).
>= 3.5
Альтернатива Python :[*l1, *l2]
Ще одна альтернатива була введена, прийняття PEP 448
якої заслуговує на згадку.
PEP під назвою " Додаткові розпаковувальні узагальнення" , як правило, зменшував деякі синтаксичні обмеження при використанні зірочного *
вираження в Python; з нею тепер об'єднання двох списків (стосується будь-якого ітерабельного):
>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2] # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]
Ця функціональність була визначена для Python,3.5
вона не підтримувалась у попередніх версіях у 3.x
родині. У непідтримуваних версіях A SyntaxError
буде піднято.
Як і в інших підходах, це теж створює дрібну копію елементів у відповідних списках.
Перевернуте цей підхід полягає в тому , що ви дійсно не потрібно списках для того , щоб виконати це, все , що ітератор буде робити. Як зазначено в ПЕП:
Це також корисно як більш читабельний спосіб підбиття ітерабелів до списку, такого,
my_list + list(my_tuple) + list(my_range)
який зараз еквівалентний справедливому[*my_list, *my_tuple, *my_range]
.
Отже, хоча додавання з +
би призвело TypeError
до невідповідності типу:
l = [1, 2, 3]
r = range(4, 7)
res = l + r
Наступне не буде:
res = [*l, *r]
тому що він спочатку розпакує вміст ітерабелів, а потім просто створить list
зі змісту.
res = [*l1, *reversed(l2)]
. Оскільки reversed
повертає ітератор, res = l1 + reversed(l2)
він видасть помилку.
Ви можете використовувати набори для отримання об'єднаного списку унікальних значень
mergedlist = list(set(listone + listtwo))
listone + [x for x in listtwo if x not in listone]
import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))
зробите свою справу.
Ви також можете скористатися list.extend()
методом, щоб додати a list
до кінця іншого:
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
Якщо ви хочете зберегти оригінальний список недоторканим, ви можете створити новий list
об’єкт та extend
обидва списки до нього:
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
Як з'єднати два списки в Python?
Станом на 3.7, це найпопулярніші методи stdlib для об'єднання двох (або більше) списків у python.
Виноски
Це гладке рішення через його лаконічність. Але
sum
виконує конкатенацію попарно, це означає, що це квадратична операція, оскільки для кожного кроку потрібно виділяти пам'ять. НЕ ВИКОРИСТОВУЙТЕ, якщо ваші списки великі.Див.
chain
Іchain.from_iterable
з док. Вам потрібноimport itertools
спочатку. Конкатенація лінійна в пам'яті, тому це найкраще з точки зору продуктивності та сумісності версій.chain.from_iterable
було введено в 2.6.Цей метод використовує додаткові генерації розпакування (PEP 448) , але не може узагальнити до N списків, якщо ви не розпакуйте кожне вручну самостійно.
a += b
іa.extend(b)
є більш-менш рівноцінними для всіх практичних цілей.+=
при виклику в списку буде внутрішній дзвінокlist.__iadd__
, який розширює перший список на другий.
З’єднання в 2 списку 1
Різниця між цими методами не велика, але це має сенс, враховуючи, що всі вони мають однаковий порядок складності (лінійний). Немає особливих причин віддавати перевагу одному над іншим, крім питання стилю.
З'єднання N-списків
Діаграми були створені за допомогою модуля perfplot . Код, для довідки.
1. iadd
( +=
) та extend
методи діють на місці, тому копія повинна створюватися кожного разу перед тестуванням. Щоб зробити справи справедливими, усі методи мають крок попередньої копії для лівого списку, який можна ігнорувати.
НЕ ВИКОРИСТОВУЙТЕ МЕТОДУ ДУНДЕРУ list.__add__
безпосередньо ні в якому разі, формі чи формі. Насправді залишайтеся осторонь методів, а також використовуйте оператори та operator
функції, як вони були розроблені. Python має ретельну семантику, яка є більш складною, ніж просто виклик кандидата безпосередньо. Ось приклад . Отже, підсумовуючи, a.__add__(b)
=> BAD; a + b
=> ДОБРО.
Деякі відповіді тут пропонують reduce(operator.add, [a, b])
парне конкатенацію - це те саме, що sum([a, b], [])
лише багатослівне.
Будь-який метод, який використовує set
, скидає копії та втрачає замовлення. Використовуйте обережно.
for i in b: a.append(i)
є більш багатослівним і повільнішим, ніж a.extend(b)
функція виклику однієї функції та ідіоматичніша. append
повільніше через семантику, з якою пам'ять виділяється та вирощується для списків. Дивіться тут для подібної дискусії.
heapq.merge
буде працювати, але випадок його використання призначений для об'єднання відсортованих списків у лінійний час. Використання його в будь-якій іншій ситуації є анти-закономірністю.
yield
Якщо список елементів з функції є прийнятним методом, але chain
робить це швидше і краще (у нього є шлях коду до C, тому він швидкий).
operator.add(a, b)
є прийнятним функціональним еквівалентом a + b
. Це випадки використання в основному для динамічного відправлення методу. В іншому випадку, віддайте перевагу, a + b
який коротший і легший для читання, на мій погляд . YMMV.
"There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.
"Рішення, не вказані у моїй відповіді, або закинуті в" Коментарі ", я рекомендую не використовувати.
Це досить просто, і я думаю, це навіть було показано в підручнику :
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
Це питання безпосередньо задає питання про об'єднання двох списків. Однак це досить високий пошук, навіть коли ви шукаєте спосіб приєднання до багатьох списків (у тому числі, коли ви приєднуєтесь до нульових списків).
Я думаю, що найкращим варіантом є використання розуміння списку:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Ви також можете створити генератори:
>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Стара відповідь
Розглянемо цей більш загальний підхід:
a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])
Виведе:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Зауважте, це також працює правильно, коли a
є []
або [[1,2,3]]
.
Однак це можна зробити ефективніше itertools
:
a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))
Якщо вам не потрібен list
, а просто ітерабельний, пропустіть list()
.
Оновлення
Альтернатива, запропонована Патріком Коллінзом у коментарях, також може підійти вам:
sum(a, [])
reduce
зараз увімкнено, functools
тому вам потрібно спочатку імпортувати його.
Ви можете просто скористатися оператором +
або +=
оператором так:
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
Або:
c = []
a = [1, 2, 3]
b = [4, 5, 6]
c += (a + b)
Крім того, якщо ви хочете, щоб значення в об'єднаному списку були унікальними, ви можете зробити:
c = list(set(a + b))
list(dict.fromkeys(a + b))
Варто зазначити, що itertools.chain
функція приймає змінну кількість аргументів:
>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']
Якщо вхід є ітерабельним (кортеж, список, генератор тощо), from_iterable
може застосовуватися метод класу:
>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
З Python 3.3+ ви можете використовувати вихід із :
listone = [1,2,3]
listtwo = [4,5,6]
def merge(l1, l2):
yield from l1
yield from l2
>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
Або, якщо ви хочете підтримати довільну кількість ітераторів:
def merge(*iters):
for it in iters:
yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]
itertools.chain
(що еквівалентно) замість визначення власної функції.
Якщо ви хочете об'єднати два списки у відсортованому вигляді, ви можете скористатися merge
функцією з heapq
бібліотеки.
from heapq import merge
a = [1, 2, 4]
b = [2, 4, 6, 7]
print list(merge(a, b))
Якщо ви не можете використовувати оператор плюс ( +
), ви можете скористатися operator
імпортом:
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
Крім того, ви також можете використовувати функцію " __add__
Дандер" :
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
+
немає за столом, використовуйте operator.add
.
Як більш загальний спосіб для більшої кількості списків, ви можете помістити їх у список та використовувати функцію itertools.chain.from_iterable()
1, яка ґрунтується на цій відповіді, є найкращим способом розшарування вкладеного списку:
>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1. Зауважте, що chain.from_iterable()
це доступно в Python 2.6 та пізніших версіях. В інших версіях використовуйте chain(*l)
.
Якщо вам потрібно об'єднати два упорядковані списки зі складними правилами сортування, можливо, вам доведеться прокрутити його самостійно, як у наведеному нижче коді (використовуючи просте правило сортування для читабельності :-)).
list1 = [1,2,5]
list2 = [2,3,4]
newlist = []
while list1 and list2:
if list1[0] == list2[0]:
newlist.append(list1.pop(0))
list2.pop(0)
elif list1[0] < list2[0]:
newlist.append(list1.pop(0))
else:
newlist.append(list2.pop(0))
if list1:
newlist.extend(list1)
if list2:
newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])
heapq.merge
.
Ви можете використовувати append()
метод, визначений на list
об'єктах:
mergedlist =[]
for elem in listone:
mergedlist.append(elem)
for elem in listtwo:
mergedlist.append(elem)
Як вже вказували багато людей, itertools.chain()
це шлях, якщо потрібно застосувати однаковий режим до обох списків. У моєму випадку я мав етикетку та прапор, які відрізнялися від одного списку до іншого, тому мені було потрібно щось трохи складніше. Як виявляється, за лаштунками itertools.chain()
просто робиться наступне:
for it in iterables:
for element in it:
yield element
(див. https://docs.python.org/2/library/itertools.html ), тому я взяв натхнення звідси і написав щось у цьому напрямку:
for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
print header + ':'
for path in iterable:
[...]
command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
print >> SCRIPT , command, flag, srcPath, mergedDirPath
[...]
Основні моменти, які слід зрозуміти тут, полягають у тому, що списки - це лише окремий випадок ітерабельності, який є об'єктами, як і будь-який інший; і ці for ... in
петлі в python можуть працювати з змінними кортежу, тому просто циклічно працювати на декількох змінних одночасно.
Використовуйте просте розуміння списку:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
Він має всі переваги найновішого підходу використання додаткових розпаковуючих узагальнень - тобто ви можете об'єднати довільну кількість різних ітерабелів (наприклад, списки, кортежі, діапазони та генератори) таким чином - і це не обмежується Python 3.5 або пізнішої версії .
Справді стислий спосіб об’єднати список списків
list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)
що дає нам
[1, 2, 3, 4, 5, 6, 7, 8, 9]
list.__add__
, operator.add
а використовуйте натомість. Це більш багатослівний еквівалент, sum(list_of_lists, [])
який так само поганий. НЕ ВИКОРИСТОВУВАТИ!
obj.__class__
і obj.__dict__
.
У Python ви можете об'єднати два масиви сумісних розмірів за допомогою цієї команди
numpy.concatenate([a,b])
Тож є два простих способи.
+
: Він створює новий список із наданих списківПриклад:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
Приклад:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop
Таким чином, ми бачимо, що з двох найпопулярніших методів extend
це ефективно.
chain.from_iterable
).
Існує кілька способів об'єднати списки в python.
l1 = [1,2,3,4]
l2 = [3,4,5,6]
1. new_list = l1.extend(l2)
2. new_list = l1 + l2
3. new_list = [*l1, *l2]
import itertools
A = list(zip([1,3,5,7,9],[2,4,6,8,10]))
B = [1,3,5,7,9]+[2,4,6,8,10]
C = list(set([1,3,5,7,9] + [2,4,6,8,10]))
D = [1,3,5,7,9]
D.append([2,4,6,8,10])
E = [1,3,5,7,9]
E.extend([2,4,6,8,10])
F = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
F.append(a)
print ("A: " + str(A))
print ("B: " + str(B))
print ("C: " + str(C))
print ("D: " + str(D))
print ("E: " + str(E))
print ("F: " + str(F))
Вихід:
A: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
B: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
C: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
D: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
Якщо ви хотіли нового списку, зберігаючи два старі списки:
def concatenate_list(listOne, listTwo):
joinedList = []
for i in listOne:
joinedList.append(i)
for j in listTwo:
joinedList.append(j)
sorted(joinedList)
return joinedList
lst1 = [1,2]
lst2 = [3,4]
def list_combinationer(Bushisms, are_funny):
for item in lst1:
lst2.append(item)
lst1n2 = sorted(lst2)
print lst1n2
list_combinationer(lst1, lst2)
[1,2,3,4]
Ви можете слідувати коду
listone = [1, 2, 3]
listtwo = [4, 5, 6]
for i in listone:
listtwo.append(i)
print(listtwo)
[1,2,3,4,5,6]