Python Forum

Full Version: Order of key and value in dictionary keeps changing
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am trying to write a code to sort out bookings for staff in a clinic. The idea is to allocate the next booking to the staff with the most availability (i.e least amount of bookings). The code and csv is as below:

import pandas as pd

def percentage_booked(staffcsv):
    with open(staffcsv) as f:
        df = pd.read_csv(f)

    stafflist = list(df.columns)
    stafflist.remove('time')
    for items in stafflist:
            occupied_slots = df[items].notnull().tolist()
            number_of_occupied_slots = occupied_slots.count(True)
            available_slots = df[items].isnull().tolist()
            number_of_available_slots = available_slots.count(True)
            percentage_of_occupied_slots = round(number_of_occupied_slots/(number_of_occupied_slots + number_of_available_slots),3)
            yield {items,percentage_of_occupied_slots}

x = percentage_booked('test.csv')
for items in x:
    print(items)
Output:
time, Staff 1 , Staff 2 , Staff 3 8:00, Adam , Alice , 9:00, , Bob , 10:00 , , ,
(the empty values are meant to represent null values)

The code runs fine, but the order of the key and value of items appears to be (semi)random with each run, like this:
Output:
PS D:\python> python test10.py {0.333, 'Staff 1'} {'Staff 2', 0.667} {0.0, 'Staff 3'} PS D:\python> python test10.py {0.333, 'Staff 1'} {0.667, 'Staff 2'} {0.0, 'Staff 3'} PS D:\python> python test10.py {0.333, 'Staff 1'} {0.667, 'Staff 2'} {0.0, 'Staff 3'} PS D:\python> python test10.py {0.333, 'Staff 1'} {0.667, 'Staff 2'} {0.0, 'Staff 3'} PS D:\python> python test10.py {0.333, 'Staff 1'} {0.667, 'Staff 2'} {'Staff 3', 0.0}
This is problematic as I intend to merge the dictionary and sort the values in ascending order, so that the next appointment can be allocated to the staff with the lowest percentage of booked slots (i.e. staff 3 in this snippet), but with the order of keys and values being random with each run, it's going to be very difficult to write a code to sort the percentages that will not throw up errors. (The code to do the sorting is still in progess; being a beginner I am still struggling to write a code that can do the sorting even if the order of the output is consistent, let alone if the order is random!).

I am curios as to why Python throws up something funny like this even though my code (line 15) explicitly calls for the percentage to be the value of the dict, and if there are any workarounds to this behaviour.

Thanks in advance.
first of all you yield set, not dict. these are two different types of collections.
yield {items:percentage_of_occupied_slots} # this will yield a dict with one key:value pair
Note that I am not sure you actually want to yield separate dict for each key:value pair

As to dict order - which is not relevant in this case:
Before 3.6 dicts were unordered collections. You need to use OrderedDict from collections module if you want ordered dict.
In 3.6 order preserving was introduced as implementation detail. from 3.7+ order pereserving feature of dicts is guaranteed.
This is if dict has more than 1 element. In your case you have only one key, value pair.
Additional tidbit to buran's excellent answer:

Whats new in Python 3.8 >>> Other language changes

Quote:Dict and dictviews are now iterable in reversed insertion order using reversed(). (Contributed by RĂ©mi Lapeyre in bpo-33462.)