gpt4 book ai didi

python - 如何使用 Python 获得 "reasonable"字符串排序?

转载 作者:太空宇宙 更新时间:2023-11-03 11:42:47 24 4
gpt4 key购买 nike

我有一些用户(主要是德国人)需要从长列表中选择元素。我将实现自动完成,但我也想按照他们期望的顺序向他们展示元素。我向几个用户询问了典型的字符串以对它们进行排序,发现它(大部分)是一致的。但是,很难实现这种排序:

user_expectation(l)                               "        <        @        1        2        10       10abc    A        e        é        E        Z
sorted(l) " 1 10 10abc 2 < @ A E Z e é
sorted(l, key=lambda w: w.lower()) " 1 10 10abc 2 < @ A e E Z é
ns.natsorted(l) 1 2 10 10abc " < @ A E Z e é
ns.natsorted(l, alg=ns.I) 1 2 10 10abc " < @ A E Z e é
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G) 1 2 10 10abc " < @ A E e Z é
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G), en 1 2 10 10abc < " @ A E e é Z
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G), de 1 2 10 10abc < " @ A E e é Z
ns.natsorted(l, alg=ns.LF | ns.G), de 1 2 10 10abc " < @ A e E Z é

因此:

  • 特殊字符优先——顺序并不重要,只要一致
  • 下一个数字。通过匹配前缀对数字进行数字排序(因此 ['1', '10', '2'])
  • 字符(Latin1?)
    • 非重音优先
    • 先小写再大写(尽管这可能不是那么重要
    • 重音/特殊的稍后

代码

# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import natsort as ns
import locale

def custom_print(name, l):
s = u"{:<50}".format(name)
for el in l:
s += u"{:<5}\t".format(el)
print(u"\t" + s.strip())

l = ['"', "<", "@", "1", "2", "10", "10abc", "A", "e", "é", "E", "Z"]
custom_print("user_expectation(l)", l)
custom_print("sorted(l)", sorted(l))
custom_print("sorted(l, key=lambda w: w.lower())",
sorted(l, key=lambda w: w.lower()))
custom_print("ns.natsorted(l)", ns.natsorted(l))
custom_print("ns.natsorted(l, alg=ns.I)", ns.natsorted(l, alg=ns.I))
custom_print("ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G)",
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G))
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
custom_print("ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G), en",
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G))
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
custom_print("ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G), de",
ns.natsorted(l, alg=ns.LOCALE | ns.LF | ns.G))
custom_print("ns.natsorted(l, alg=ns.LF | ns.G), de",
ns.natsorted(l, alg=ns.LF | ns.G))

natsortIGNORECASELOWERCASEFIRSTLOCALE(de 或 en)、GROUP flags非常接近。我不喜欢的是特殊字符在数字之后。有办法解决吗? (而且LF好像没有效果)

最佳答案

natsort 版本 >= 5.1.0 开始,应立即处理重音字符。

这是一种在数字之前获取特殊字符的方法。

import re
import natsort as ns

def special_chars_first(x):
'''Ensure special characters are sorted first.'''
# You can add error handling here if needed.
# If you need '_' to be considered a special character,
# use [0-9A-Za-z] instead of \W.
return re.sub(r'^(\W)', r'0\1', x)
# An alternate, less-hacky solution.
#if re.match(r'\W', x):
# return float('-inf'), x
#else:
# return float('inf'), x

l = ['"', "<", "@", "1", "2", "10", "10abc", "A", "e", "é", "E", "Z"]
print(ns.natsorted(l, key=special_chars_first, alg=ns.G | ns.LF))

输出

['"', '<', '@', '1', '2', '10', '10abc', 'A', 'e', 'é', 'E', 'Z']

这通过在任何以非单词字符(定义为除字母、数字或 '_' 之外的任何字符)开头的字符串前面加上 '0' 来实现这将保证它们在任何其他数字之前结束(并且根据现在 natsort 的工作,数字总是第一个)。

关于python - 如何使用 Python 获得 "reasonable"字符串排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45734562/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com