Скажем, у меня есть список
l = [1,2,3]
и я хочу суммировать каждый элемент в списке с каждым другим элементом в списке. Я мог бы сделать это:
x = [(a, b) for a in l for b in l]
y = [(a + b) for a in l for b in l]
x = [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
y = [2, 3, 4, 3, 4, 5, 4, 5, 6]
Является ли назначение двух переменных (a
и b
) элементам в одном списке (l
) лучшим способом доступа и выполнения операций с этими элементами? Есть лучший способ сделать это?
Я просмотрел список методов и функций и не смог их найти.
ОБНОВИТЬ
Многие люди рекомендовали функцию продукта itertools, поэтому я подумал, что включу время, прежде чем пометить как ответ:
mysetup = """
from itertools import product
l = [10, 15, 3, 7]
k = 17
"""
mycode = """
[i for i in product(l, repeat=2)]
"""
t = timeit.timeit(setup=mysetup, stmt=mycode, number=100000)
# 0.1505305
mysetup2 = """
l = [10, 15, 3, 7]
k = 17
"""
mycode2 = """
[(a, b) for a in l for b in l]
"""
t1 = timeit.timeit(setup=mysetup2, stmt=mycode2, number=100000)
# 0.1432976
Попробуйте использовать itertools.product
, который получает каждую комбинацию последовательности:
>>> from itertools import product
>>> l = [1,2,3]
>>> list(product(l, repeat=2))
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
>>> list(map(sum, product(l, repeat=2)))
[2, 3, 4, 3, 4, 5, 4, 5, 6]
>>>
Попробуйте это, itertools.продукт
>>> from itertools import product
>>> l = [1,2,3]
>>> [sum(combination) for combination in list(product(l, repeat = 2))]
[2, 3, 4, 3, 4, 5, 4, 5, 6]
@ThierryLathuille Спасибо за указание. Ответ был обновлен с помощью product
.
Вот подход, основанный на itertools
:
from operator import add
from itertools import product, starmap
l = [1,2,3]
list(starmap(add, product(l, repeat=2)))
# [2, 3, 4, 3, 4, 5, 4, 5, 6]
Давайте проверим тайминги:
l = list(range(1000))
%timeit list(map(sum, product(l, repeat=2)))
# 187 ms ± 14.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit [sum(combination) for combination in combinations_with_replacement(l, 2)]
# 123 ms ± 4.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
list(starmap(add, product(l, repeat=2)))
# 102 ms ± 4.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
combinations_with_replacement
не дает те же значения, что и product
- он не дает пары в обратном порядке, поэтому он примерно в два раза быстрее...
Спасибо, что указали на @ThierryLathuille, действительно здесь мы хотим декартово произведение.
Python предоставляет встроенный метод
from itertools import product
l = [1,2,3]
Затем сгенерируйте сумму, используя понимание списка за один шаг, чтобы быть более эффективным.
result= [sum(i) for i in product(l, repeat= 2) ]
#result=[2, 3, 4, 3, 4, 5, 4, 5, 6]
combinations_with_replacement
не дает тех значений, которые хотел ОП. Вместо этого вы должны использоватьproduct
, но синхронизация показывает, что он медленнее, чем код в вопросе.