mike.js3
mike.js3

Reputation: 13

How to compare indices of a list to a float?

Nested list to be iterated over

cost =[[125900], [115000],
[105900],
[85000],
[150000],
[155249],
[97500]]

Initialize variables

index = 0
cost_len = len(cost)
below_avg = 0
above_avg = 0
total = 0

For loop to calculate the total of all elements in cost

 for i in cost:
    total = total + sum(i)
    print(total)

Calculating the average of cost

avg = total / len(cost)

Attempt to calculate whether indices are above or below avg

for i in cost:
    while index <= cost_len:
        if i > avg:
            above_avg+=1
        elif i < avg:
            below_avg +=1
        index+=1

When attempting to evaluate the indices of cost, it returns "TypeError: unorderable types: list() > float()". How would I compare the indices of the list with the variable avg?

Upvotes: 1

Views: 220

Answers (3)

Mad Physicist
Mad Physicist

Reputation: 114460

There is no need to flatten the list if you want to compare multiple elements in each sublist:

total = sum(sum(x) for x in cost)
cost_len = sum(len(x) for x in cost)
avg = total / cost_len
above = sum([sum([y > avg for y in x for x in cost])])
below = sum([sum([y < avg for y in x for x in cost])])
exact = cost_len - (above + below)

A couple of points about this solution:

  1. The computation for total and cost_len use generators instead of creating lists from the results. This saves you some memory and possibly execution time since intermediate results do not require additional storage.
  2. above and below are nested generators, basically equivalent to the nested loop you were trying to do.

Here is an explanation of what your final nested loop does and how to fix it:

for i in cost:
    while index <= cost_len:
        if i > avg:
            above_avg+=1
        elif i < avg:
            below_avg +=1
        index+=1

i loops over the elements of cost, but the inner while loop prevents it from doing anything after the first value of i is processed. Notice that the value of i does not change in the inner loop, so the comparisons are done over and over for the first i, and not at all for the others since index will be cost_len + 1 by then. To preserve the double loop structure you have, you can do as follows:

for i in cost:
    for j in i:
        if j > avg:
            above_avg+=1
        elif j < avg:
            below_avg +=1

At that point, you do not really need index.

Upvotes: 0

Back2Basics
Back2Basics

Reputation: 7806

If you are going to be dealing with lists of numbers or arrays of numbers then I would suggest you use Numpy (http://docs.scipy.org/doc/numpy/user/index.html) for this task:

import numpy as np

cost = np.array([[125900],
 [115000],
 [105900],
 [85000],
 [150000],
 [155249],
 [97500]])

cost-np.average(cost)

>>>array([[  6678.71428571],
       [ -4221.28571429],
       [-13321.28571429],
       [-34221.28571429],
       [ 30778.71428571],
       [ 36027.71428571],
       [-21721.28571429]])

The cost - np.average(cost) is a way to use Numpy's broadcasting feature. You can subtract a single value (np.average(cost)) from an array (cost) and it will do the subtraction for the whole array which gives you the answer array.

Upvotes: 0

Mike M&#252;ller
Mike M&#252;ller

Reputation: 85512

Assuming one element per sub-list, flatten seems to be the best:

flat_cost = [x[0] for x in cost]
total = sum(flat_cost)
avg = total /len(cost)
above = len([x for x in flat_cost if x > avg])
below = len([x for x in flat_cost if x < avg])

Upvotes: 1

Related Questions