2012-05-18 2 views
6

У меня вопрос: Это список списков, образованных в ElementTree.Custom sort python

[['word1', <Element tag at b719a4cc>], ['word2', <Element tag at b719a6cc>], ['word3', <Element tag at b719a78c>], ['word4', <Element tag at b719a82c>]] 

Слово1..4 может содержать символы юникода i.e (â, ü, ç).

Я хочу отсортировать этот список списков по своему произвольному алфавиту.

Я знаю, как сортировать по настраиваемому алфавиту здесь sorting words in python

Я также знаю, как сортировать по ключу здесь http://wiki.python.org/moin/HowTo/Sorting

Проблема заключается в том, что я не мог найти способ, как применить эти два метода сортировать мой «список списков».

+1

Файн вопрос, если вы указали достаточный код, который мы могли бы запустить его, я держал пари, что кто-то просто опубликуйте полное решение (особенно, если вы публикуете то, что вы пробовали). –

+0

Я согласен с Брайаном, добавлю код, который мы можем скопировать и вставить, и, вероятно, потребуется менее 5 минут, чтобы написать полностью рабочий ответ. –

+0

Привет! У меня есть еще одна проблема. Как сделать сортировку ** нечувствительной к регистру **? – microspace

ответ

13

Ваша первая ссылка более или менее решает проблему. Вам просто нужно иметь функцию лямбда смотреть только на первой позиции в списке:

alphabet = "zyxwvutsrqpomnlkjihgfedcba" 

new_list = sorted(inputList, key=lambda word: [alphabet.index(c) for c in word[0]]) 

Одна из модификаций я мог бы предложить, если вы сортировки достаточно большой список, чтобы изменить структуру алфавита в Словаре во-первых, чтобы ускорить поиск индекса:

alphabet_dict = dict([(x, alphabet.index(x)) for x in alphabet) 
new_list = sorted(inputList, key=lambda word: [alphabet_dict[c] for c in word[0]]) 
2

Если я правильно понимаю вас, вы хотите знать, как применять метод сортировки ключей, когда ключ должен применяться к элементу вашего объекта. Другими словами, вы хотите применить ключевую функцию к «wordx», а не к элементу ['wordx', ...], который вы фактически сортируете. В этом случае, вы можете сделать это:

my_alphabet = "..." 

def my_key(elem): 
    word = elem[0] 
    return [my_alphabet.index(c) for c in word] 

my_list.sort(key=my_key) 

или используя стиль в первой ссылке:

my_alphabet = "..." 
my_list.sort(key=lambda elem: [my_alphabet.index(c) for c in elem[0]]) 

Имейте в виду, что my_list.sort будет сортировать на месте, на самом деле изменения списка. sorted (my_list, ...) вернет новый отсортированный список.

+0

Да, вы поняли меня правильно. Спасибо! Теперь я понимаю. – microspace

0

Прекрасно работает! Спасибо за помощь. Вот моя история: У меня есть турецко-русский словарь в формате xdxf. проблема заключалась в ее сортировке. Я нашел решение здесь http://effbot.org/zone/element-sort.htm, но он не сортировал символы Юникода. здесь является окончательным исходный код: содержание

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import xml.etree.ElementTree as ET 
import codecs 
alphabet = u"aâbcçdefgğhiıjklmnoöpqrstuüvwxyz" 
tree = ET.parse("dict.xml") 
# this element holds the phonebook entries 
container = tree.find("entries") 
data = [] 
for elem in container: 
    keyd = elem.findtext("k") 
    data.append([keyd, elem]) 
data.sort(key=lambda data: [alphabet.index(c) for c in data[0]]) 
container[:] = [item[-1] for item in data] 
tree.write("new-dict.xml", encoding="utf-8") 

образец dict.xml

<cont> 
    <entries> 
<ar><k>â</k>def1</ar> 
<ar><k>a</k>def1</ar> 
<ar><k>g</k>def1</ar> 
<ar><k>w</k>def1</ar> 
<ar><k>n</k>def1</ar> 
<ar><k>u</k>def1</ar> 
<ar><k>ü</k>def1</ar> 
<ar><k>âb</k>def1</ar> 
<ar><k>ç</k>def1</ar> 
<ar><k>v</k>def1</ar> 
<ar><k>ac</k>def1</ar> 
    </entries> 
</cont> 

Спасибо всем

+0

Ммм. У меня еще одна проблема. Как сделать его нечувствительным к регистру? – microspace