Как перевести эту функцию генератора на лямбда-выражение

У меня такая же проблема, и она была решена путем установки «proxyUser» и «proxyPassword» в системных свойствах.

System.setProperty("http.proxyUser", PROXY_USER);
System.setProperty("http.proxyPassword", PROXY_PASSWORD);

вместе с «proxyHost» и «proxyPort»

System.setProperty("http.proxyHost", PROXY_ADDRESS);
System.setProperty("http.proxyPort", PROXY_PORT);

Надеюсь, что это сработает.

3
задан Trickee 13 July 2018 в 04:12
поделиться

3 ответа

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

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
ответ дан dawg 17 August 2018 в 13:41
поделиться
  • 1
    Почему reduce(add, nums[0:i]) - это не то же самое, что sum(nums[0:i]) и enumerate() кажутся странным способом получить range(1, len(nums)+1). – AChampion 13 July 2018 в 05:06
  • 2
    В этом случае да, но параллельно с возможностью accumulate принять вызываемый. – dawg 13 July 2018 в 05:07

Это один из способов сделать это:

nums=[1,2,3,4]

[sum(nums[:idx+1]) for idx, i in enumerate(nums)]

Выход:

[1, 3, 6, 10]

Другой способ - использовать itertools.accumulate , как было предложено by @Blckknght.

from itertools import accumulate

list(accumulate(nums))

Выход:

[1, 3, 6, 10]
4
ответ дан Ashish Acharya 17 August 2018 в 13:41
поделиться
  • 1
    Предупреждение: O(n^2) сложность. Используйте это только в действительно небольших списках ... – dawg 13 July 2018 в 16:22

Если список постоянно.

Простой, но не эффективный способ:

[sum(range(1, i+1)) for i in range(1, 5))]

Выход:

[1, 3, 6, 10]

0
ответ дан Cyrbuzz 17 August 2018 в 13:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: