Sorting a combined list of numbers and letters in Python
<p>I am trying to sort a list in Python, but one containing both letters and numbers in the same term. The problem with using sort on a string is that it doesn't sort the numbers correctly:</p>

<pre><code>2
23
3
</code></pre>

<p>etc</p>

<pre><code>list = [("a", ['8', '0']), ("a", ['7', '0b']), ("a", ['7', '0']), ("a", ['6', '0b']), ("a", ['6', '01']]

new_list = sorted(list, key=lambda i: i[1]) 
# works great on ints.
</code></pre>

<p>The letters need to be sorted as there number equivalent, ie:</p>

<pre><code>a = 1, b = 2, c = 3, d = 4 etc
</code></pre>

<p>hence <code>4.1a</code> == <code>4.11</code></p>

<p>But I need to preserve the letter in the output and not just convert it to an int. Any ideas?</p>

<p>It's not totally clear from your question, but I assume that you are ignoring the first item in each tuple, and only sorting on the list in the second item. I also assume that <em>only</em> letters from 'a' to 'i' can occur in in that list. </p>

<p>A simple way to convert a -> 1, b -> 2, c -> 3, ... i -> 9 is to take advantage of the fact that the ASCII codes of the digit characters are contiguous and so are the lower case letters. Thus there's a constant offset of 48 between each letter and its equivalent digit.</p>

<p>So to convert a list of strings to a key we can join all the strings into a single string, then convert each letter char in the string into its equivalent digit char, join the resulting chars back into a single string, and convert that string to an integer.</p>

<pre><code>lst = [
    ("a", ['8', '0']), 
    ("a", ['7', '0b']), 
    ("a", ['7', '0']), 
    ("a", ['6', '0b']), 
    ("a", ['6', '01']),
]

def keyfunc(t):
    a = [chr(ord(c) - 48) if 'a' &lt;= c &lt;= 'i' else c for c in ''.join(t[1])]
    return int(''.join(a))

new_lst = sorted(lst, key=keyfunc)
for row in new_lst:
    print(row)
</code></pre>

<p><strong>output</strong></p>

<pre><code>('a', ['7', '0'])
('a', ['8', '0'])
('a', ['6', '01'])
('a', ['6', '0b'])
('a', ['7', '0b'])
</code></pre>

<p>BTW, you should not use <code>list</code> as a variable name, as that shadows the built-in <code>list</code> type, and that can lead to mysterious bugs.</p>

python list python-2.7 sorting