python字符串排序_如何使用Python进行“合理”的字符串排序?

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

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

natsort与IGNORECASE,LOWERCASEFIRST,LOCALE(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,sorting,natsort

来源: https://codeday.me/bug/20190705/1390660.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值