A team trained several models and measured each one in the same way: for example accuracy (higher is better), size in MB (lower is better) and prediction time in ms (lower is better). The directions are given as a string better with one character per measure: ">" means higher is better, "<" means lower is better.
Model A beats model B when A is at least as good as B in every measure and strictly better in at least one. A model is worth keeping when no other model beats it.
Write worth_keeping(models, better) where models is a list of (name, scores) pairs and scores is a tuple with one number per measure. Return the names of the models worth keeping, in their input order.
Examples
Input: models = [("big", (0.95, 400, 30)),
("small", (0.91, 20, 4)),
("mid", (0.91, 60, 9)),
("tiny", (0.80, 5, 2))]
better = "><<"
Output: ["big", "small", "tiny"]
Explanation: small beats mid: equal accuracy, and smaller and faster.
Nothing beats big (most accurate) or tiny (smallest and fastest).
Input: models = [("a", (1, 1)), ("b", (1, 1))], better = "<<"
Output: ["a", "b"]
Explanation: Identical scores: neither is strictly better anywhere, so neither beats the other.
The setup defines random_models(n, d, seed), a list of n models with d random measures, so you can try your function with Run.
Constraints
0 <= len(models) <= 300,1 <= len(better) <= 6- every
scorestuple haslen(better)numbers; names are distinct.
Goals
- Express "no worse everywhere and better somewhere" with `all` and `any` over zipped values
- Bring measures with opposite directions to a common direction before comparing
- Filter a list by a condition that looks at every other item