Элементарное добавление 2 списков?
Теперь у меня есть:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
Я хочу иметь:
[1, 2, 3]
+ + +
[4, 5, 6]
|| || ||
[5, 7, 9]
Просто поэлементное добавление двух списков.
Я, конечно, могу повторить два списка, но я не хочу этого делать.
Какой самый питонский способ сделать это?
Ответы
Ответ 1
Используйте map
с operator.add
:
>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]
или zip
с пониманием списка:
>>> [sum(x) for x in zip(list1, list2)]
[5, 7, 9]
Сроки сравнения:
>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in zip(list1, list2)]
1 loops, best of 3: 177 ms per loop
Ответ 2
Другие привели примеры, как это сделать на чистом питоне. Если вы хотите сделать это с массивами с 100.000 элементов, вы должны использовать numpy:
In [1]: import numpy as np
In [2]: vector1 = np.array([1, 2, 3])
In [3]: vector2 = np.array([4, 5, 6])
Выполнение поэлементного добавления теперь так же тривиально, как и
In [4]: sum_vector = vector1 + vector2
In [5]: print sum_vector
[5 7 9]
так же, как в Matlab.
Сроки, чтобы сравнить с самой быстрой версией Ashwini:
In [16]: from operator import add
In [17]: n = 10**5
In [18]: vector2 = np.tile([4,5,6], n)
In [19]: vector1 = np.tile([1,2,3], n)
In [20]: list1 = [1,2,3]*n
In [21]: list2 = [4,5,6]*n
In [22]: timeit map(add, list1, list2)
10 loops, best of 3: 26.9 ms per loop
In [23]: timeit vector1 + vector2
1000 loops, best of 3: 1.06 ms per loop
Так что это в 25 раз быстрее! Но используйте то, что подходит вашей ситуации. Для простой программы вы, вероятно, не хотите устанавливать numpy, поэтому используйте стандартный python (и я считаю версию Генри самой Pythonic). Если вы серьезно переживаете за число, позвольте numpy
сделать тяжелую работу. Для фанатов скорости: кажется, что решение с пустышкой быстрее начинается с n = 8
.
Ответ 3
[a + b for a, b in zip(list1, list2)]
Ответ 4
Как описано другими, быстрое, а также эффективное решение пространства использует numpy (np) с встроенной возможностью векторной обработки:
1. С Numpy
x = np.array([1,2,3])
y = np.array([2,3,4])
print x+y
2. С встроенными функциями
2.1 Лямбда
list1=[1, 2, 3]
list2=[4, 5, 6]
print map(lambda x,y:x+y, list1, list2)
Обратите внимание, что map() поддерживает несколько аргументов.
2.2 zip и понимание списка
list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in zip(list1, list2)]
Ответ 5
На мой взгляд проще использовать numpy
:
import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)
Результаты:
![Terminal execution]()
Для получения подробной информации о параметрах, проверьте здесь: numpy.add
Ответ 6
Это просто с numpy.add()
import numpy
list1 = numpy.array([1, 2, 3])
list2 = numpy.array([4, 5, 6])
result = numpy.add(list1, list2) # result receive element-wise addition of list1 and list2
print(result)
array([5, 7, 9])
Смотрите документ здесь
Если вы хотите получить список питонов:
result.tolist()
Ответ 7
Возможно, "самый питонический путь" должен включать обработку случая, когда list1 и list2 не имеют одинакового размера. Применение некоторых из этих методов позволит вам дать ответ. Метод numpy позволит вам узнать, скорее всего, с помощью ValueError.
Пример:
import numpy as np
>>> list1 = [ 1, 2 ]
>>> list2 = [ 1, 2, 3]
>>> list3 = [ 1 ]
>>> [a + b for a, b in zip(list1, list2)]
[2, 4]
>>> [a + b for a, b in zip(list1, list3)]
[2]
>>> a = np.array (list1)
>>> b = np.array (list2)
>>> a+b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2) (3)
Какой результат вы хотите, если бы это было в функции в вашей проблеме?
Ответ 8
Это будет работать для 2 или более списков; итерации по списку списков, но с помощью добавления numpy для обработки элементов каждого списка
import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]
lists = [list1, list2]
list_sum = np.zeros(len(list1))
for i in lists:
list_sum += i
list_sum = list_sum.tolist()
[5.0, 7.0, 9.0]
Ответ 9
Возможно, это питон и немного полезен, если у вас есть неизвестное количество списков, и ничего не импортировать.
Пока списки имеют одинаковую длину, вы можете использовать функцию ниже.
Здесь * args принимает переменное число аргументов списка (но только суммирует одинаковое количество элементов в каждом).
* Снова используется в возвращаемом списке, чтобы распаковать элементы в каждом из списков.
def sum_lists(*args):
return list(map(sum, zip(*args)))
a = [1,2,3]
b = [1,2,3]
sum_lists(a,b)
Выход:
[2, 4, 6]
Или с 3 списками
sum_lists([5,5,5,5,5], [10,10,10,10,10], [4,4,4,4,4])
Выход:
[19, 19, 19, 19, 19]
Ответ 10
Использовать карту с лямбда-функцией:
>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]
Ответ 11
Я не приурочил его, но я подозреваю, что это будет довольно быстро:
import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]
list_sum = (np.add(list1, list2)).tolist()
[5, 7, 9]
Ответ 12
Если вам нужно обрабатывать списки разных размеров, не беспокойтесь! Замечательный itertools модуль вы рассмотрели:
>>> from itertools import zip_longest
>>> list1 = [1,2,1]
>>> list2 = [2,1,2,3]
>>> [sum(x) for x in zip_longest(list1, list2, fillvalue=0)]
[3, 3, 3, 3]
>>>
В Python 2 zip_longest
называется izip_longest
.
См. также этот ответ и комментарий по другому вопросу.
Ответ 13
[list1[i] + list2[i] for i in range(len(list1))]
Ответ 14
Хотя, фактический вопрос не хочет перебирать список для генерации результата, но все предлагаемые решения делают именно то, что находится под капотом!
Чтобы обновить: вы не можете добавить два вектора, не просматривая все векторные элементы. Таким образом, алгоритмическая сложность большинства этих решений - Big-O (n). Где n - размерность вектора.
Итак, с алгоритмической точки зрения, используя цикл for для итеративного генерации, результирующий список также является логическим и питоническим. Однако, кроме того, этот метод не имеет накладных расходов на вызов или импорт какой-либо дополнительной библиотеки.
# Assumption: The lists are of equal length.
resultList = [list1[i] + list2[i] for i in range(len(list1))]
Тайминги, которые показываются/обсуждаются здесь, зависят от системы и реализации и не могут быть надежной мерой для измерения эффективности операции. В любом случае большая сложность операции вектора сложения O является линейной, что означает O (n).
Ответ 15
a_list = []
b_list = []
for i in range(1,100):
a_list.append(random.randint(1,100))
for i in range(1,100):
a_list.append(random.randint(101,200))
[sum(x) for x in zip(a_list , b_list )]