Как настроить материал веб-компонентов с помощью laravel-mix?

Я хотел бы предложить следующее в качестве замены для этого:

nums=[1,2,3,4]
gen=(sum(li[0:i]) for i,_ in enumerate(li,1))

Это генератор, поэтому операция O(n^2) не выполняется для элементов, которые еще не нужны.

Затем, чтобы получить элементы, используйте next:

>>> next(gen)
1
>>> next(gen)
3
>>> next(gen)
6
>>> next(gen)
10

И если вы действительно хотите их всех сразу, просто используйте list в генераторе:

>>> gen=(reduce(add, li[0:i]) for i,_ in enumerate(li,1))
>>> list(gen)
[1, 3, 6, 10]]

Производительность этой функции в нетривиальных списках HARRIBLE, поскольку она имеет сложность O(n^2). Используйте его только как любопытство. См. Тайминги ниже.


И (благодаря AChampion) другое сокращение:

>>> reduce(lambda x, y: x+[y+next(iter(x[-1:]), 0)], nums, [])
[1, 3, 6, 10]

Но правильный ответ - itertools.accumulate или ваша оригинальная функция. Любое однострочное решение будет иметь гораздо большую вычислительную сложность.


Вот набор таймингов, чтобы показать, что кроме itertools.accumulate, для замены одной строки есть сложность типа O(n^2) (т. Е. 10x больше предметов, примерно в 100 раз больше). Это потому, что для каждого элемента в списке, поскольку lambdas или сокращение или понимание не имеют какой-либо формы аккумулятора, весь список до этой точки должен быть зациклен снова. Ваша исходная функция и itertools.accumulate - это сложность типа O(n) (т. Е. 10x больше элементов, линейное 10x больше времени).

Здесь - график и диаграмма O Сложность.

Вот время и результаты:

from itertools import accumulate
from functools import reduce 

def f1(nums):
    sum_ = 0
    for i in nums:
        sum_ += i
        yield sum_

def f2(nums):
    return (sum(nums[0:i]) for i,_ in enumerate(nums,1))

def f3(nums):
    return  accumulate(nums)

def f4(nums):
    return reduce(lambda x, y: x+[y+next(iter(x[-1:]), 0)], nums, [])

if __name__=='__main__':
    import timeit    
    for case, x in (('small',100),('med',1000),('large',10000),('huge',100000)):  
        data=list(range(x))
        print("Case {}, {:,} x, All equal: {}".format(case,x,(list(f1(data))==list(f2(data))==list(f3(data))==list(f4(data)))))
        for f in (f1,f2,f3,f4):
            print("   {:^10s}{:.4f} secs".format(f.__name__, timeit.timeit("list(f(data))", setup="from __main__ import f, data", number=10)))

Результаты:

Case small, 100 x, All equal: True
       f1    0.0001 secs
       f2    0.0007 secs
       f3    0.0000 secs
       f4    0.0006 secs
Case med, 1,000 x, All equal: True
       f1    0.0007 secs
       f2    0.0424 secs
       f3    0.0003 secs
       f4    0.0139 secs
Case large, 10,000 x, All equal: True
       f1    0.0083 secs
       f2    3.9526 secs
       f3    0.0036 secs
       f4    1.2756 secs
Case huge, 100,000 x, All equal: True
       f1    0.0977 secs
       f2    427.4129 secs
       f3    0.0532 secs
       f4    159.2506 secs

1
задан Vega 20 January 2019 в 11:02
поделиться