I am writing a small optimization tool for buying stamps at the post office.
In the process, I use a dictionary that I sort according to what I found out on this other “famous” question: Sort Python dictionary by value
In my case, my dictionary is slightly more complex:
- one four-position tuple to make a key
- and another set of five elements to make data .
The source of this dictionary is iteration, where each successful loop adds one line:
MyDicco[A, B, C, D] = eval, post, number, types, over
This is just a tiny example of a trivial run using 75 cents:
{
(0, 0, 1, 1): ( 22 , 75, 2, 2, 0)
(0, 0, 0, 3): ( 31 , 75, 3, 1, 0)
(0, 0, 2, 0): ( 2521 , 100, 2, 1, 25)
(0, 1, 0, 0): ( 12511 , 200, 1, 1, 125)
(1, 0, 0, 0): ( 27511 , 350, 1, 1, 275)
}
So far, I'm using this code for sorting (works):
MyDiccoSorted = sorted(MyDicco.items(), key=operator.itemgetter(1))
I sort by my score, because sorting is all about bringing the best solution to the top. Evaluation-evaluation is just one point from a tuple of five objects (in the example, these are evaluation-ratings: 22, 31, 2521, 12511 and 27511).
As you can see in the above example, it sorts (as I want) the second tuple, index 1. But I had to (angrily) bring my "grade point" to the foreground of my second tuple. Obviously, the code uses the entire second tuple for sorting process, which is heavy and not needed.
Here is my question: how can I sort more accurately. I do not want to sort through the entire second tuple of my dictionary: I want to fine-tune the first element.
And ideally, I would like to return this value to its original position, namely to be the last element in the second tuple - and still sort it.
I read and experimented with the operator.itemgetter () syntax, but I was not able to just “capture” the “first element of my second element”. https://docs.python.org/3/library/operator.html?highlight=operator.itemgetter#operator.itemgetter
(note: it is permissible to use tuples as keys and values, in accordance with:
https://docs.python.org/3/tutorial/datastructures.html?highlight=dictionary and they work fine for my project; this question is about better sorting)
For those who like a little background (you will yell at me that I should use some other method, but now I'm studying dictionaries (which is one of the goals of this project)):
This optimization is intended for developing countries, where often certain brand values are absent or limited in stock at any post office. It will later work on Android phones.
We do regular mailings (yes, letters). Calculating the exact postage for each destination with available values and finding solutions with low stocks of certain values is not a trivial process if you count six different mail items based on the destination and hundreds of letters to be sent by mail.
There are other modules that help turn a theoretical optimal solution into something that you can really buy any day with a strategic dialogue guide ...
About my vocabulary in this matter: I sort through all the reasonable combinations (high enough to make the necessary postage and only overpayment up to a fraction of one mark) of stamped values.
Then I calculate the “success” value based on the number of required brands (priority), the number of required types (lower priority) (since buying different brands takes extra time on the counter) and a very high penalty for paying. Thus, the lowest value means the highest success.
I collect all reasonable "solutions" in the dictionary, where the tuple of the necessary stamps serves as the key, and another set of some results - the data are the values. It is gently redefined, because a person needs to read it at this stage of the project (for debugging).
If you are interested and want to read an example (first line):
Columns:
- 350 cents stamps
- number of stamps 200 cents
- number of stamps at 50 cents
- number of stamps at 25 cents
- assessment-assessment
- estimated applicable postage
- total number of applied brands
- total number of stamp types
- overpayment in cents, if any
Or in words: (Assuming that the postal service offers existing stamps of 350, 200, 50 and 25 cents), I can apply postage of 75 cents using 1 x 50 cents and 1 x 25 cents, This gives me a success rating of 22 (the best on this list), postage is 75 cents, requiring two stamps of two different values and having overfulfillment of 0 cents.