【问题标题】:Python: Custom sort a list of listsPython:自定义排序列表列表
【发布时间】:2015-02-09 07:22:06
【问题描述】:

我知道以前有人问过这个问题,但我一直没能找到解决办法。

我正在尝试根据自定义字母表按字母顺序排列列表列表。

字母表是Burmese script 的表示,Sgaw Karen 使用纯 ASCII 格式。缅甸文字是一个字母表——几十个声母、几个中间变音符号和几十个可以以数千种不同方式组合的押韵,每一个都是代表一个音节的单个“字符”。 map.txt 文件有这些音节,按(克伦语/缅甸语)字母顺序列出,但以某种未知方式转换为 ASCII 符号,因此第一个字符是 u>m;.Rf 而不是 က[ka̰]。例如:

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

列表列表中的每个列表都具有作为其第一个元素的 Sgaw Karen 单词,以相同的方式转换为 ASCII 符号。例如:

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

这是我目前所拥有的:

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

我想根据alphabet 中的模式按每个列表的第一个元素(例如'u&X>'、'vk.')对word_list 进行字母排序。

我的代码还没有工作,我很难理解带有 lambda 和 for 循环的排序命令。

【问题讨论】:

  • 这些模式是什么意思? (在map.txt)?文件是什么样的?
  • 在什么方面它还没有工作? alphabet 中有什么内容,哪些值排序错误?
  • 另外,当参数将是一个单词的 list 时使用参数名称 word 似乎是一件非常令人困惑的事情,并且可能是原因是您难以理解您的代码。将lambda 转换为外线def 也可能会有所帮助,因此您可以在不同的值上手动调用它并查看它返回的内容(这样您就不会将所有内容打包成一个巨大的表达式超出屏幕边缘;如果有帮助,您可以将 listcomp 展开为 for 循环,给事物起临时名称等)。
  • u&X> 不在您的字母字符串中,vk.w>ouDxD.... 也不存在时如何索引?
  • 我没有发布整个序列,因为它真的很长。

标签: python list sorting sorted


【解决方案1】:

首先,如果您要在alphabet 中查找整个word[0],而不是单独查找每个字符,则不应循环遍历word[0] 的字符。直接使用alphabet.index(word[0])即可。

从您的 cmets 看来,您正在尝试查找 word[0] 中的每个缅甸音译字符。这是不可能的,除非您可以编写一个算法将一个单词分成这些字符。将其拆分为音译的 ASCII 字节根本没有帮助。


其次,您可能不应该在这里使用index。当您认为需要使用index 或类似功能时,90% 的情况下,这意味着您使用了错误的数据结构。你在这里想要的是一个映射(大概是为什么它被称为map.txt),就像一个字典,以单词为键,而不是你必须明确搜索的单词列表。然后,在该词典中查找一个单词是微不足道的。 (它更高效,但它易于阅读和理解这一事实可能更重要。)


最后,我怀疑您的map.txt 应该被读取为以空格分隔的音译字符列表,而您想要找到的是该列表中任何给定单词的索引。


所以,把它们放在一起,就像这样:

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]])

但是,同样,这仅适用于单音节单词,因为在您弄清楚如何将单词拆分为应按字母顺序排列的单元(在本例中为符号)之前,没有办法使其适用于多音节单词。

一旦您编写了执行此操作的代码,我敢打赌,将所有内容转换为缅甸脚本的正确 Unicode 表示会很容易。每个音节在 Unicode 中仍然需要 1-4 个代码点——但这很好,因为 Python 内置的标准 Unicode 排序算法已经知道如何为该脚本正确地按字母顺序排列,所以你不必编写自己动手。

或者,更好的是,除非这是您或您的老师发明的一些奇怪的音译,否则可能已经有代码可以在这种格式和 Unicode 之间进行转换,这意味着您甚至不必自己编写任何东西。

【讨论】:

  • 感谢 cmets。让我试着更清楚地了解 map.txt 文件是什么。它不一定是单词列表。空白是无关紧要的。它更像是一个大长字符串,其功能与 'abcdefghijklmnopqrstuvwxyz' 相同。定义该语言中哪些字符排在其他字符之前。
  • @DenverSmith:所以“字符”是指字符——u,然后是>,然后是m,等等?但是这些字符中的大多数都是一遍又一遍地出现,那么“来之前”是什么意思呢?
  • @DenverSmith:如果您试图从按字母顺序排列的单词列表中推断字符顺序,那是行不通的。例如,大多数 Unix 系统附带的标准英语词典以 a aa aal aalii aam 开头,所以它会告诉你 l 是字母表中的第二个字母,b 是第 10 个。
  • 所以在这种语言 (Sgaw Karen) 中,每个字符至少由一个辅音和一个元音组成,可能还有一个声调。映射文件中的文本从第一个辅音开始,然后是每个元音,然后是每个音调,然后移动到第二个辅音,依此类推。也许有更好的方法来存储/组织这些数据,它似乎不应该那么复杂。希望这是有道理的。谢谢。
  • @DenverSmith 首先,将足够的信息放入问题中真的很有帮助,而不是让我们从你那里挖出来,然后让其他想要帮助的人阅读几十个厘米。其次,那 still 没有回答任何问题。如果字母表是一个音节(如日文假名),而words.txt 是那些音节被音译成一个由空格分隔的“单位”……那么我的代码正是你想要的。另一方面,如果它实际上是一个单词列表(无论是否按字母顺序排列),那么您遇到的问题与我上一条评论中的问题相同。
猜你喜欢
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多