Dr.squid
Dr.squid

Reputation: 1

how to make lists from big list containing numbers as floats

here is a list (its a short one for example) this is from a survey and is stored in sqlite database as tuple which I converted into list

bmi=[ 38.09, 23.15, 41, 22.35, 18.6, 28.3 ]

expecting output bmi1 = [23.15, 22.35,] . i want to seperate the numbers into different lists by their ranges example 20 to 25 one list, 25 to 30 another. etc. how can i do that i tried "for loop" but it shows floats cannot be iteratable. basically how can i loop floating numbers and make new lists

Upvotes: 0

Views: 47

Answers (1)

ottomeister
ottomeister

Reputation: 5828

Try this:

from collections import defaultdict

bmis = [ 38.09, 23.15, 41, 22.35, 18.6, 28.3 ]

buckets = defaultdict(list)

def bucket_name(n):
    ''' Return the name of the bucket that should hold the given 'n' '''
    return 5 * int(n / 5)   # round down to the nearest multiple of 5

for bmi in bmis:
    buckets[bucket_name(bmi)].append(bmi)      

That should build a dictionary whose keys are the starting points of the ranges (15, 20, 25, ...) and whose values are lists containing the numbers that belong in each range. With the example input it will look like this:

    {
        40: [41],
        25: [28.3],
        35: [38.09],
        20: [23.15, 22.35],
        15: [18.6]
    }

OP asked:

can you explain a bit ...

I'm guessing the defaultdict is the part you haven't seen before.

An ordinary dict will throw an exception if you try to read an item that does not exist in the dict. So if buckets was an ordinary dict if you were trying to place a value into the 20 bucket you might do this:

    buckets[20].append(bmi)

to get the current 20 item, which it expects to be a list, and then it appends the new bmi to that list. However, if the buckets dict did not already contain a 20 item then that line would fail and throw an exception. To get the program to work with an ordinary dict you would have to add extra code to deal with the case where the bucket item you want to use does not already exist. It's not a ton of extra code, but makes the program logic more complex. It would look something like this:

buckets = {}    # an empty ordinary dict

for bmi in bmis:
    bucket = bucket_name(bmi)
    if bucket not in buckets:
        buckets[bucket] = [ bmi ]    # a new list with one element
    else:
        buckets[bucket].append(bmi)

A defaultdict solves this problem. If you try to read an item from a defaultdict but that item does not already exist, the defaultdict automatically creates the item, gives it a default value, and then returns that default value to your program. So you don't have to have extra code to deal with creating an item if it doesn't already exist.

When you create a defaultdict dictionary you specify the name of a function that it will call to get the default value of an automatically-created item. So this line:

buckets = defaultdict(list)

creates a defaultdict that will create new entries automatically and set them to the value returned by calling the list function. list is a standard built-in Python function that returns an empty list. So the buckets variable is a dictionary that automatically creates new items whose initial value is an empty list. That means that if we do:

    buckets[20].append(bmi)

when a buckets[20] item does not already exist, it will be created automatically as a new empty list [] and then the bmi value will be appended to that list, producing a list with bmi as its only member. With the defaultdict there is no extra logic to check whether the item exists before you use it (or no exception that needs to be caught and handled, if you wanted to deal with it that way).

The documentation for defaultdict is here. It's a little terse, but the examples are helpful.

Upvotes: 1

Related Questions