【问题标题】:How to sort a list of strings with a different order?如何以不同的顺序对字符串列表进行排序?
【发布时间】:2016-05-20 20:37:49
【问题描述】:

我正在用 Python 编写一个可以对我的列表进行排序的函数。问题是我不希望它与sorted() 方法使用的顺序相同。我尝试使用sorting() 方法,但是当我对这个字符串进行排序时,我会这样:

0123456789abcdefghijklmnopqrstuvwxyzßàáäåæçèéêìíîñòóôöøùúüžα

我希望它的顺序是:

0123456789aàáäåæbcçdeèéêfghiìíîjklmnñoòóôöøpqrsßtuùúüvwxyzžα

现在,我有一个这样的列表(示例):

list = ['x', 'h', 'ê', 'ø', '5', 'ž', 'z', 'α', '3', '1']

我想对它进行排序。如果我使用sorted() 方法,它看起来像这样:

['1', '3', '5', 'h', 'x', 'z', 'ê', 'ø', 'ž', 'α']

但我希望它与我之前给出的字符串的顺序相同。

【问题讨论】:

  • 参见python tutorial on sorting,尤其是key 函数的第二个。你想要像key = lambda s: reference.index(s) 这样的东西,其中引用是你在上面列出的字符串,并具有正确的排序顺序。
  • 您的答案的第一部分在于sortedkey 参数。第二部分是描述该关键功能。显而易见的方法是硬编码的dict 将“a”的所有变体映射到'a'。自己想出这个可能很难,因为有很多 Unicode 字符是 ASCII 字母的变体,比如“a”。 (“带有组合矢量箭头的 a”算吗?)这样的函数可能已经在某个库中可用。
  • 没有。这些是我唯一需要使用的字符!
  • @KevinJ.Chase 我看不出这个问题有两个“部分”。问题是如何实现自定义排序顺序(基于要在提供的字符串中排序的每个对象的位置)。我选择了我的副本,因为该问题本质上是基于自定义顺序(基于提供的列表中的位置)排序的,抽象地相同的问题和解决方案可以在这种情况下使用,只需最少的修改。

标签: python list sorting character


【解决方案1】:

想法是按照指定的顺序将索引关联到每个char,并使用字符串chars的索引进行顺序比较。

注意:仅适用于 Python 3

对一个字符字符串进行排序

ORDER = "0123456789aàáäåæbcçdeèéêfghiìíîjklmnñoòóôöøpqrsßtuùúüvwxyzžα"
# associate each char with the index in the string
# this makes sort faster for multiple invocations when compared with
# ORDER.index(c)
POS = {c:p for (p, c) in enumerate(ORDER)}

lst = ['x', 'h', 'ê', 'ø', '5', 'ž', 'z', 'α', '3', '1']

lst.sort(key = lambda c: POS[c])
# or, suggested by wim
lst.sort(key = POS.get)

对任意长度的字符串进行排序

class MyStrOrder:
    def __init__(self, inner):
        self.inner = inner

    def __lt__(self, other):
        for i in range(min(len(self.inner), len(other.inner))):
            a = POS.get(self.inner[i])
            b = POS.get(other.inner[i])
            if a != b:
                return a < b
        return len(self.inner) < len(other.inner)

lst = ["abc", "ab", "aá"]
lst.sort()
print(lst)

lst = ["abc", "ab", "aá"]
lst.sort(key = MyStrOrder)
print(lst)

输出:

['ab', 'abc', 'aá']
['aá', 'ab', 'abc']

【讨论】:

  • @wim 这是一个很好的建议。谢谢。
  • 这对单字符串非常有效。我不知道这对于 OP 是否足够,但如果您可以将其推广到任意长度的字符串,那么答案对于年龄来说会更有用。
  • @MarkRansom 我更新了答案。感谢您的建议。
  • __lt__ 中有一个小错误,当一个字符串是另一个字符串的子集时它会失败。您可以通过将return False 替换为return len(a) &lt; len(b) 来修复它。有人应该提到这是 Python 3,其中字符串默认为 Unicode。
  • 我看到你修正了答案,还破译了我的意图,而不是我的错误指示。干得好!
猜你喜欢
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 2023-01-25
  • 2014-11-08
  • 2021-07-08
  • 1970-01-01
相关资源
最近更新 更多