简体   繁体   中英

Python - sum of integers in a list (recursive)

I am trying to make a program that returns the sum of all integers in a list, bigger than n or equal to n. For example,

>>>floorSum([1,3,2,5,7,1,2,8], 4)
20

Here is the code I came up with:

def floorSum(l,n):
    if len(l)>0:
        if l[0]<n:
            floorSum(l[1:],n)
        else:
            s=l[0]+floorSum(l[1:],n)
    return s

I am getting: UnboundLocalError: local variable 's' referenced before assignment.

Any ideas?

you forgot to initialize s to zero

def floorSum(l,n):
    s = 0
    if len(l) > 0:
        if l[0] < n:
            s = floorSum(l[1:], n)
        else:
            s = l[0] + floorSum(l[1:], n)
    else:
         return 0
    return s

As others pointed out, you neglected to initialize s for all cases and check for a length of zero.

Here's an alternative approach:

def floorSum(l, n):
    if len(l) > 1:
        mid = len(l) // 2  # Python 3 integer division
        return floorSum(l[:mid], n) + floorSum(l[mid:], n)
    if len(l) == 1 and l[0] >= n:
        return l[0]
    return 0

This version will divide the list into halves at each step, so although it doesn't do any less work the depth of the recursion stack is O(log(len(l))) rather than O(len(l)). That will prevent stack overflow for large lists.

Another benefit of this approach is the additional storage requirements. Python is creating sublists in both versions, but in your original version the additional storage required for the sublists is (n-1) + (n-2) + ... + 1 , which is O(n 2 ). With the successive halving approach, the additional storage requirement is O(n log n), which is substantially lower for large values of n. Allocating and freeing that additional storage may even impact the run time for large n. (Note, however, that this can be avoided in both algorithms by passing the indices of the range of interest as arguments rather than creating sublists.)

Thanks I solved the problem!

Forgot to put s=0

Python is a wonderful language that allows you to do that in a single line with list comprehension.

s = sum([value for value in l if value >= n])

Another way is to use filter

s = sum(filter(lambda e: e >= n, l))

The first one basically says:

"Create a new list from the elements of l , so that they are all greater or equal to n . Sum that new list."

The second one:

"Filter only the elements that are greater or equal to n . Sum over that."

You can find ample documentation on both of these techniques.

If you found the answer useful, mark it as accepted

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM