简体   繁体   中英

Summing elements based on threshold

I was doing my homework when I encountered this problem:

Write a function, mysum_bigger_than , that works the same as mysum , except that it takes a first argument that precedes *args . That argument indicates the threshold for including an argument in the sum. Thus, calling mysum_bigger _than(10, 5, 20, 30, 6) would return 50 —because 5 and 6 aren't greater than 10 . This function should similarly work with any type and assumes that all of the arguments are of the same type. Note that '>' and '<' work on many different types in Python, not just on numbers; with strings, lists, and tuples, it refers to their sort order.

THE PROBLEM WITH THE CODE UNDERNEATH: I can't sum elements which are bigger than threshold value without threshold value itself!

def mysum_bigger_than(*values):
    if not values:
        return values
    output = values[0]
    for value in values[1:]:
        if value < output:
            continue
        else:
            output += value 
    return output

print(mysum_bigger_than(10,5,20,30,6)) #returns 60 instead of 50
print(mysum_bigger_than('mno', 'abc', 'pqr', 'uvw', 'efg', 'xyz')) #returns everything i need with unnecessary 'mno'

One problem with your attempt: You use the threshold ( output ) as a starting point of the summation. Another: You check for bigger and equal than the threshold. And I think you should actually model your function signature according to this part of the instructions:

... except that it takes a first argument that precedes *args ...

So

def mysum_bigger_than(threshold, *values):

This has the advantage that (1) without providing a threshold the function would return an error. And (2) you don't have to separate the threshold from the values list in the function definition.

Here's a suggestion:

def mysum_bigger_than(threshold, *values):
    summing = False
    result = None
    for value in values:
        if value > threshold:
            if summing:
                result += value
            else:
                result = value
                summing = True
    return result

summing is a control variable: It's value is False as long as the values in values are below the threshold. Once the first value is above the threshold it's value is set to True . And at the same time the result variable gets "properly" initialized and is used afterwards as summation variable. If no value in values is above the threshold the function returns None , otherwise the required sum.

Here's another suggestion, which is more compact but probably not as efficient (which would only matter for an extremely large values list):

def mysum_bigger_than(threshold, *values):
    sum_values = [value for value in values if value > threshold]
    if not sum_values:
        return None
    result = sum_values[0]
    for value in sum_values[1:]:
        result += value
    return result

The first step filters those values from values that meet the requirement of being bigger than the threshold (using a list comprehension). The next step checks if there are actually values that are bigger than the threshold. The function returns None if that's not the case. The rest is just summing up over the filtered values, if there are any.

If you're allowed to, you could use some tools from the standard library, reduce and add :

from functools import reduce
from operator import add

def mysum_bigger_than(threshold, *values):
    sum_values = [value for value in values if value > threshold]
    if not sum_values:
        return None
    return reduce(add, sum_values)

But I think this is a bit overkill.

(One thing you definitely shouldn't use here is sum , because by design it doesn't work for strings.)

Try this approach:

def mysum_bigger_than(*values):
    if not values:
        return values
    cond = lambda x: x > values[0]
    return sum(filter(cond, values[1:]))

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