Вот как я бы упростил функцию:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
И сравнение между оригинальным и модифицированным:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Результаты сравнения:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT . О плаваниях в Python.
Использование >= 1
в этом самом коде не должно быть проблемой практически в любом случае. Но рассмотрим пример:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
должен быть равен нулю после всех этих операций, но на моем компьютере a
equlas to -6.938893903907228e-18
, потому что точность ограничена. Вы должны учитывать этот факт, когда хотите проверить равенство между числами.