As @NullUserException said, you can't do the sort in two steps, because the second step will reshuffle based only on the middle column, ignoring the first (str) column.
You can do the sorting in one shot after transforming the data appropriately, and you don't have to worry about keys:
s='''ABC - 0.2 - 15
BAC - 1.2 - 10
ABC - 1.3 - 29
ABC - 0.7 - 11'''
data = s.split('\n')
data
Out[5]: ['ABC - 0.2 - 15', 'BAC - 1.2 - 10', 'ABC - 1.3 - 29', 'ABC - 0.7 - 11']
newdata = [(i[0],float(i[1]),i[2]) for i in [k.split(' - ') for k in data]]
newdata
Out[10]:
[('ABC', 0.2, '15'),
('BAC', 1.2, '10'),
('ABC', 1.3, '29'),
('ABC', 0.7, '11')]
sorted(newdata)
Out[11]:
[('ABC', 0.2, '15'),
('ABC', 0.7, '11'),
('ABC', 1.3, '29'),
('BAC', 1.2, '10')]
Another approach: using a lambda key may be the easier way to go if the input data restructure requires a lot of manipulation:
# data is a list of strings
data = ['ABC - 0.2 - 15', 'BAC - 1.2 - 10', 'ABC - 1.3 - 29', 'ABC - 0.7 - 11']
# My key is now a lambda function that extracts the
# sortable parts, and assembles them in a tuple.
# Note how easy it would be to change the sort order,
# just order the entries in the inner tuple differently.
# If data is some other array-like structure, just change
# how the inner data is accessed when building your tuple.
sorted(data, key=lambda x: (x.split(' - ')[0], float(x.split(' - ')[1])))
Out[18]: ['ABC - 0.2 - 15', 'ABC - 0.7 - 11', 'ABC - 1.3 - 29', 'BAC - 1.2 - 10']