How I want to order my list:
My list contains these NamedTuple:
class Font(NamedTuple):
fontPath: str
fontName: str
isRegular: bool
bold: bool
italic: bool
weight: int
Here is now how I sorted it (which is not good)
fontMatch.sort(key=lambda font: (-font.isRegular, -font.bold, -font.italic, -abs(400 - font.weight)))
Input
[
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Thin_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=250),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Light_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=300),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Medium_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=500),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Regular_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=True, bold=False, italic=False, weight=400),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY ExtraBold_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=800),
Font(fontPath='C:\\Windows\\Fonts\\Deleted\\MADE TOMMY BOLD_PERSONAL USE.OTF', fontName='MADE TOMMY', isRegular=False, bold=True, italic=False, weight=700),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Black_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=900),
]
Output I currently have (if I try to run the code multiple time, it will give me different output. I have no idea why it does that. Here is 2 output example I can get)
# Output 1
[
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Regular_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=True, bold=False, italic=False, weight=400),
Font(fontPath='C:\\Windows\\Fonts\\Deleted\\MADE TOMMY BOLD_PERSONAL USE.OTF', fontName='MADE TOMMY', isRegular=False, bold=True, italic=False, weight=700),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Thin_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=250),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Light_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=300),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Black_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=900),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Medium_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=500),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY ExtraBold_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=800)
]
# Output 2
[
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Regular_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=True, bold=False, italic=False, weight=400),
Font(fontPath='C:\\Windows\\Fonts\\Deleted\\MADE TOMMY BOLD_PERSONAL USE.OTF', fontName='MADE TOMMY', isRegular=False, bold=True, italic=False, weight=700),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Black_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=900),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY ExtraBold_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=800),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Thin_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=250),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Medium_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=500),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Light_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=300),
]
Here is the output I want
[
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Regular_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=True, bold=False, italic=False, weight=400),
Font(fontPath='C:\\Windows\\Fonts\\Deleted\\MADE TOMMY BOLD_PERSONAL USE.OTF', fontName='MADE TOMMY', isRegular=False, bold=True, italic=False, weight=700),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Medium_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=500),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Light_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=300),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Thin_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=250),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY ExtraBold_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=800),
Font(fontPath='C:\\Windows\\Fonts\\MADE TOMMY Black_PERSONAL USE.otf', fontName='MADE TOMMY', isRegular=False, bold=False, italic=False, weight=900)
]
list.sort()
is ascending by default. You don't need to do -abs(400 - font.weight)
. Just remove the negative sign at the front:
fontMatch.sort(key=lambda font: (-font.isRegular, -font.bold, -font.italic, abs(400 - font.weight)))
Note: For the case of 300 and 500 (equal distance from 400), the 300 will be placed first since it is sorted in ascending order. If you want it the other way round, include -font.weight
in the tuple like so:
fontMatch.sort(key=lambda font: (-font.isRegular, -font.bold, -font.italic, abs(400 - font.weight), -font.weight))