16

I want to return a function which gives the average of all the marks which are 50 or more. When I run my code, it always returns an empty list.

Here is what I have tried:

def get_pass_average(marks):
    average = []
    for count in marks:
        if count >= 50:
           average = sum(count) / len(count)          
    return round(average,2)

def test_get_pass_average():
    list1 = [50, 83, 26, 65, 92, 29, 77, 64]
    print('%.2f' % (get_pass_average(list1)))

Please help me to figure out the problems in my code, and the output should be 71.83.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
Chiu Chiu
  • 175
  • 1
  • 3
  • 2
    For the question in title, OP can just [filter out](https://stackoverflow.com/questions/4587915/return-list-of-items-in-list-greater-than-some-value) and [compute average](https://stackoverflow.com/questions/9039961/finding-the-average-of-a-list). You don't need to provide the answer again. – user202729 Sep 23 '18 at 14:43
  • 1
    Also remember to specify which Python version you're using, with a [tag:python-2.7] or [tag:python-3.x] tag. `/` behaves differently in both versions. – user202729 Sep 23 '18 at 14:47

6 Answers6

17

Try this:

l=[i for i in list1 if i>=50]
print(sum(l)/len(l))

Or:

from statistics import mean
l=[i for i in list1 if i>=50]
print(mean(l))

If want to condition for empty lists:

l=[i for i in list1 if i>=50]
if l:
    print(sum(l)/len(l))

Or:

from statistics import mean
l=[i for i in list1 if i>=50]
if l:
    print(mean(l))

For python 2:

print(sum(l)/len(l))

Should be:

print(float(sum(l))/float(len(l)))

And no statistics module.

Your code doesn't work because you're summing the iterator (an integer) not the list so that's why it's not working

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
15

In addition to U9-Forward's answer, one using filter and mean:

from statistics import mean

list1 = [50, 83, 26, 65, 92, 29, 77, 64]
average = mean(filter((50).__le__, list1))
print('%.2f' % average)
Daniel
  • 42,087
  • 4
  • 55
  • 81
11

To answer the question of:

Please helps me to figure out the problems in my code

The issue are the lines of:

for count in marks
    if count >= 50:
        average = sum( count ) / len( count )

marks is a list of integers. Hence, when you loop for count in marks, the value of count is an integer. I tested your code in both Python 3.6.3 and 2.7.10, and you can't even call the sum() and len() functions on an integer (they both return a TypeError if you try).

You initialize average = [], so it seems like you expect average to contain a list, but even if sum( count ) = count and len( count ) = 1, then average contains an integer, not a list.

I'd be to curious to know which version of Python you're using that allows this code to execute without error.

Corrections for these errors have already been given.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
David M.
  • 381
  • 3
  • 10
2

Actually, the code you provided does not return an empty list as you state, it actually asserts with a TypeError, assuming you actually call the test_get_pass_average() function, something that's not clear in your code:

Traceback (most recent call last):
  File "testprog.py", line 12, in <module>
    test_get_pass_average()
  File "testprog.py", line 10, in test_get_pass_average
    print('%.2f' % (get_pass_average(list1)))
  File "testprog.py", line 5, in get_pass_average
    average = sum(count) / len(count)          
TypeError: 'int' object is not iterable

It may be you're assuming it prints an empty list because there's no output but, unless you call the test function, there won't be any output, simply because the code you provide defines two functions but does nothing else.

The reason your code asserts (when you call it) is simply because you pass a non-iterable int variable to sum(). The sum() function requires an iterable since it iterates over each item to calculate the sum - you cannot iterate over a single integer (even if you could, the len() would fail because an int type has no such function:

TypeError: object of type 'int' has no len()

And the reason you're trying to do this to an int is because the construct:

for variable in [3,1,4,1,5,9]:

will iterate over that list, setting variable to each element in turn. So variable will be an int, incapable of being subjected to either sum() or len().


In terms of fixing it, the following function gives you a general solution to what you need, the average of all numbers greater than or equal to a certain threshold, and allowing a specific result if no numbers are available (defaults to None):

def AverageWithThreshold(myList, threshold, emptyResult = None):
    newList = [item for item in myList if item >= threshold]
    if len(newList) == 0: return emptyResult
    return sum(newList) / len(newList)

For your specific case, you can call it with something like (we assume the average of an empty list should be zero here):

print('%.2f' % (AverageWithThreshold(list1, 50, 0)))
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
2

Almost everything else is covered, filter has a use here as well

l = list(filter(lambda x: x >= 50, marks))
print('%.2f' % (sum(l)/len(l)))
71.83

To explain what's wrong with your code:

  • You're summing the the iterator (integer) for average.

  • And also you're getting the length of it, where you can't because it's a integer.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
vash_the_stampede
  • 4,590
  • 1
  • 8
  • 20
1

Store values and calculate the average later instead of trying to calculate the average inside for loop.

Hope you are looking for this:

def get_pass_average(marks):
    marksAbove = []
    for count in marks:
        if count >= 50:
            marksAbove.append(count);

    average = sum(marksAbove) / len(marksAbove)  
    return round(average,2)

def test_get_pass_average():
    list1 = [50, 83, 26, 65, 92, 29, 77, 64]
    print('%.2f' % (get_pass_average(list1)))

# Init
test_get_pass_average()
Pranab Mitra
  • 401
  • 1
  • 4
  • 9