Какой самый эффективный способ создать список, пропорциональный самому себе? - PullRequest
0 голосов
/ 04 марта 2020

Я хочу сделать список, такой как следующий элемент, основанный на значении предыдущего элемента. Это решение хорошо, но я хочу знать, есть ли более эффективный способ создания этого списка.

def addelement(stop, x,y):
'''stop is to end the recursion, x is the list, y is the element being appended to x'''
    if stop == 0:
        return x
    x.append(y)
    return addelement(stop-1,x,y-1)

lis = addelement(10, [], 10)
print(lis)
# returns : [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Ответы [ 4 ]

1 голос
/ 05 марта 2020

Наиболее эффективным способом является использование Python встроенных функций:

lis = list(range(10, 0, -1))

Как это бывает, оно также наиболее читабельно.

Если, однако, вы настаиваете на собственной рекурсивной функции, вероятно, все же лучше не использовать дополнительные параметры, а комбинировать возвращаемое значение с добавляемым элементом:

def addelement(stop):
    if stop == 0:
        return []
    return [stop] + addelement(stop-1)

print(addelement(10))
0 голосов
/ 05 марта 2020
>>> [*range(10, 0, -1)]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Некоторые тайминги:

PS C:\Users\...> 1..10 | % { python -m timeit "[*range(10, 0, -1)]" }
500000 loops, best of 5: 457 nsec per loop
500000 loops, best of 5: 475 nsec per loop
500000 loops, best of 5: 453 nsec per loop
500000 loops, best of 5: 485 nsec per loop
500000 loops, best of 5: 463 nsec per loop
500000 loops, best of 5: 489 nsec per loop
500000 loops, best of 5: 481 nsec per loop
500000 loops, best of 5: 469 nsec per loop
500000 loops, best of 5: 484 nsec per loop
500000 loops, best of 5: 455 nsec per loop

PS C:\Users\...> 1..10 | % { python -m timeit "list(range(10, 0, -1))" }
500000 loops, best of 5: 604 nsec per loop
500000 loops, best of 5: 597 nsec per loop
500000 loops, best of 5: 578 nsec per loop
500000 loops, best of 5: 589 nsec per loop
500000 loops, best of 5: 576 nsec per loop
500000 loops, best of 5: 572 nsec per loop
500000 loops, best of 5: 581 nsec per loop
500000 loops, best of 5: 581 nsec per loop
500000 loops, best of 5: 595 nsec per loop
500000 loops, best of 5: 595 nsec per loop

PS C:\Users\...> 1..10 | % { python -m timeit "[i for i in range(10, 0, -1)]" }
200000 loops, best of 5: 909 nsec per loop
200000 loops, best of 5: 923 nsec per loop
500000 loops, best of 5: 883 nsec per loop
500000 loops, best of 5: 954 nsec per loop
500000 loops, best of 5: 910 nsec per loop
500000 loops, best of 5: 909 nsec per loop
200000 loops, best of 5: 941 nsec per loop
500000 loops, best of 5: 894 nsec per loop
500000 loops, best of 5: 882 nsec per loop
500000 loops, best of 5: 911 nsec per loop
0 голосов
/ 05 марта 2020

если вы хотите рекурсивный подход, вы можете использовать:

def gen_nums(n):
    if n > 0:
        yield n
        yield from gen_nums(n - 1)

list(gen_nums(10))

output:

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

, но лучше следующее (уже указано @ Błotosmętek):

list(range(10, 0, -1))
0 голосов
/ 05 марта 2020

Узнайте о списках. В этом случае вы можете создать тот же список в эффективном однострочнике без рекурсии:

lis = [i for i in range(10, 0, -1)]
...