Для объединения отсортированных последовательностей вы можете использовать heapq.merge
:
import heapq
print list(heapq.merge(xrange(3, 20, 3), xrange(5, 20, 5)))
# -> [3, 5, 6, 9, 10, 12, 15, 15, 18]
Чтобы удалить дубликаты, вы можете использовать unique_justseen
рецепт из документации itertools :
print list(unique_justseen([3, 5, 6, 9, 10, 12, 15, 15, 18]))
# -> [3, 5, 6, 9, 10, 12, 15, 18]
В этом случае unique_justseen()
можно упростить до:
from itertools import groupby, imap
from operator import itemgetter
def unique_justseen(iterable):
return imap(itemgetter(0), groupby(iterable))
Эти функции не требуют, чтобы входные аргументы были последовательностями. Они принимают произвольные итерации (включая бесконечные), например, чтобы генерировать бесконечную последовательность, кратную 3 или 5:
import heapq
from itertools import count, takewhile
m3, m5 = count(3, 3), count(5, 5)
m3_5 = heapq.merge(m3, m5)
uniq_m3_5 = unique_justseen(m3_5) # *all* unique multiples of 3 or 5
Чтобы найти решение:
print sum(takewhile(lambda x: x < 1000, uniq_m3_5))
# -> 233168
# check that it is correct
print sum(set(range(3, 1000, 3) + range(5, 1000, 5)))
# -> 233168
print sum(x for x in xrange(1000) if x % 3 == 0 or x % 5 == 0)
# -> 233168
print sumk(3, 1000) + sumk(5, 1000) - sumk(15, 1000)
# -> 233168
Где sumk()
:
def sumk(k, n):
m = (n-1)//k
return k*m*(m+1)//2
Формула взята из ссылки Википедии , предоставленной @ralu.