我必须以与sorted
函数非常相似的方式对字符串列表进行排序,但有一个重要的区别。如您所知,sorted
函数会占用空格字符前一个数字字符,因此sorted(['1 ', ' 9'])
会为我们提供[' 9', '1 ']
。我需要sorted
来计算空格字符之前的数字字符,因此在我们的示例中,结果将为['1 ', ' 9']
。
据我了解,默认情况下,sorted
行为依赖于ascii'字母表中的字符顺序' (即''.join([chr(i) for i in range(59, 127)])
),所以我决定实施自己的ascii'字母表'在my_ord
函数中。
我计划将此功能与简单my_sort
功能结合使用,作为sorted
的键,
def my_ord(c):
punctuation1 = ''.join([chr(i) for i in range(32, 48)])
other_stuff = ''.join([chr(i) for i in range(59, 127)])
my_alphabet = string.digits + punctuation1 + other_stuff
return my_alphabet.find(c)
def my_sort(w):
return sorted(w, key=my_ord)
像这样:sorted([' 1 ', 'abc', ' zz zz', '9 '], key=my_sort)
。
我在这种情况下期待的是['9 ', ' 1 ', ' zz zz', 'abc']
。不幸的是,结果不仅与预期不符 - 而且,它不时有所不同。
答案 0 :(得分:2)
您可以使用lstrip
作为关键函数来忽略字符串左前方的空格。
r = sorted(['1 ', ' 9' , ' 4', '2 '], key=str.lstrip)
# r == ['1 ', '2 ', ' 4', ' 9']
key
指定一个参数的函数,用于从每个列表元素doc中提取比较键。
答案 1 :(得分:1)
试试这个
import string
MY_ALPHABET = (
string.digits
+ ''.join([chr(i) for i in range(32, 127) if chr(i) not in string.digits])
)
inp = [' 1 ', 'abc', ' zz zz', '9 ', 'a 1', 'a ']
print(inp, '-->', sorted(inp, key=lambda w: [MY_ALPHABET.index(c) for c in w]))
答案 2 :(得分:0)
您需要词法和数字排序的组合。您可以通过将字符串切换为元组并将数字转换为int
来实现。现在,元组比较将根据自己的比较规则考虑每个元素。
我使用正则表达式将字符串拆分为(开始文本,空格,数字,其他所有内容)创建int
并将其用于密钥。如果字符串与模式不匹配,它只返回元组中的原始字符串,以便它也可以用于比较。
我在数字之后移动了数字(组(2))之前的空格,但是将它完全从比较中删除可能更有意义。
import re
test = ['1 ', ' 9']
wanted = ['1 ', ' 9']
def sort_key(val):
"""Return tuple of (text, int, spaces, remainder) or just
(text) suitable for sorting text lexagraphically but embedded
number numerically"""
m = re.match(r"(.*?)(\s*)(\d+)(.*)", val)
if m:
return (m.group(1), int(m.group(3)), m.group(2), m.group(4))
else:
return (val,)
result = sorted(test, key=sort_key)
print(test, '-->', result)
assert result == wanted, "results compare"
答案 3 :(得分:0)
为了完整性和极端情况下的效率,这里有一个使用numpy argsort的解决方案:
UIViewController
总的来说,我认为使用sorted(...,key = ...)通常是优越的,如果输入已经是一个numpy数组,这个解决方案更有意义。另一方面,它每个项目只使用一次strip()并使用numpy,因此对于足够大的列表,它可能更快。此外,它会生成顺序,whitch显示每个已排序元素在原始列表中的位置。
作为最后一条评论,从您提供的代码中,但不是您提供的示例,我不确定您是否只想剥离前导空格,或者执行更多操作,例如: best-way-to-strip-punctuation-from-a-string-in-python,或者没有标点符号的字符串上的第一个顺序,然后如果它们相等,则按顺序排序(tdelaney的解决方案)无论如何编译模式可能不是一个坏主意,例如
import numpy as np
lst = ['1 ', ' 9' , ' 4', '2 ']
order = np.argsort(np.array([s.lstrip() for s in lst]))
result = list(np.array(lst)[order])
或:
import numpy as np
import re
pattern = re.compile(r'[^\w]')
lst = ['1 ', ' 9' , ' 4', '2 ']
order = np.argsort(np.array([pattern.sub('',s) for s in lst]))
result = list(np.array(lst)[order])