Tough List Comprehension Split Letters and Numbers
Padraic Cunningham nailed the shortest form in his comment:

" ".join(x for x in s.split() if not x.isdigit()) + " | " + "".join(sorted(x for x in s if x.isdigit()))


Explanation:


x for x in s.split() if not x.isdigit() -- the list of words that don't have digits. Note that the split method without parameters uses space as the separator.
x for x in s if x.isdigit() -- the list of digits extracted from the string, unsorted
From the above 2 it's easy to combine to get the desired result.


Although this is short, it checks every letter twice, first using not x.isdigit() to get only the letters and then x.isdigit() to get only the digits. We could improve that by using a helper function to partition the list of words on the outcome of x.isdigit(), like this:

def partition(pred, iterable):
    trues = []
    falses = []
    for item in iterable:
        if pred(item):
            trues.append(item)
        else:
            falses.append(item)
    return trues, falses

nums, words = partition(str.isdigit, s.split())
' '.join(words) + ' | ' + ''.join(sorted(''.join(nums)))


Of course, this is much more than one line...