Python: Custom sort a list of lists
Question: I know this has been asked before, but I have not been able to find a
solution.

I'm trying to alphabetize a list of lists according to a custom alphabet.

The alphabet is a representation of the [Burmese
script](http://en.wikipedia.org/wiki/Burmese_alphabet) as used by [Sgaw
Karen](http://en.wikipedia.org/wiki/Karen_languages) in plain ASCII. The
Burmese script is an alphasyllabary—a few dozen onsets, a handful of medial
diacritics, and a few dozen rhymes that can be combined in thousands of
different ways, each of which is a single "character" representing one
syllable. The `map.txt` file has these syllables, listed in (Karen/Burmese)
alphabetical order, but converted in some unknown way into ASCII symbols, so
the first character is `u>m;.Rf` rather than `က` or `[ka̰]`. For example:

    
    
    u>m;.Rf ug>m;.Rf uH>m;.Rf uX>m;.Rf uk>m;.Rf ul>m;.Rf uh>m;.Rf uJ>m;.Rf ud>m;.Rf uD>m;.Rf u->m;.Rf uj>m;.Rf us>m;.Rf uV>m;.Rf uG>m;.Rf uU>m;.Rf uS>m;.Rf u+>m;.Rf uO>m;.Rf uF>m;.Rf
    c>m;.Rf cg>m;.Rf cH>m;.Rf cX>m;.Rf ck>m;.Rf cl>m;.Rf ch>m;.Rf cJ>m;.Rf cd>m;.Rf cD>m;.Rf c->m;.Rf cj>m;.Rf cs>m;.Rf cV>m;.Rf cG>m;.Rf cU>m;.Rf cS>m;.Rf c+>m;.Rf cO>m;.Rf cF>m;.Rf
    

Each list in the list of lists has, as its first element, a word of Sgaw Karen
converted into ASCII symbols in the same way. For example:

    
    
    [['u&X>', 'n', 'yard'], ['vk.', 'n', 'yarn'], ['w>ouDxD.', 'n', 'yawn'], ['w>wuDxD.', 'n', 'yawn']]
    

* * *

This is what I have so far:

    
    
    def alphabetize(word_list):
        alphabet = ''.join([line.rstrip() for line in open('map.txt', 'rb')])
        word_list = sorted(word_list, key=lambda word: [alphabet.index(c) for c in word[0]])
        return word_list
    

I would like to alphabetize `word_list` by the first element of each list (eg.
'u&X>', 'vk.'), according to the pattern in `alphabet`.

My code's not working yet and I'm struggling to understand the sorted command
with lambda and the for loop.


Answer: First, if you're trying to look up the entire `word[0]` in `alphabet`, rather
than each character individually, you shouldn't be looping over the characters
of `word[0]`. Just use `alphabet.index(word[0])` directly.

From your comments, it sounds like you're trying to look up each
_transliterated-Burmese-script character_ in `word[0]`. That isn't possible
unless you can write an algorithm to split a word up into those characters.
Splitting it up into the ASCII bytes of the transliteration doesn't help at
all.

* * *

Second, you probably shouldn't be using `index` here. When you think you need
to use `index` or similar functions, 90% of the time, that means you're using
the wrong data structure. What you want here is a _mapping_ (presumably why
it's called `map.txt`), like a dict, keyed by words, not a list of words that
you have to keep explicitly searching. Then, looking up a word in that
dictionary is trivial. (It's _also_ a whole lot more efficient, but the fact
that it's easy to read and understand can be even more important.)

* * *

Finally, I suspect that your `map.txt` is supposed to be read as a whitespace-
separated list of transliterated characters, and what you want to find is the
index into that list for any given word.

* * *

So, putting it all together, something like this:

    
    
    with open('map.txt', 'rb') as f:
        mapping = {word: index for index, word in enumerate(f.read().split())}
    word_list = sorted(word_list, key=lambda word: mapping[word[0]])
    

* * *

But, again, that's only going to work for one-syllable words, because until
you can figure out how to split a word up into the units that should be
alphabetized (in this case, the symbols), there is no way to make it work for
multi-syllable words.

And once you've written the code that does that, I'll bet it would be pretty
easy to just convert everything to proper Unicode representations of the
Burmese script. Each syllable still takes 1-4 code points in Unicode—but
that's fine, because the standard Unicode collation algorithm, which comes
built-in with Python, already knows how to alphabetize things properly for
that script, so you don't have to write it yourself.

Or, even better, unless this is some weird transliteration that you or your
teacher invented, there's probably already code to translate between this
format and Unicode, which means you shouldn't even have to write anything
yourself.

