4

我的目标是对一个字符串列表进行排序,其中单词必须按字母顺序排序。除了以“s”开头的单词应该在列表的开头(它们也应该排序),然后是其他单词。

下面的函数为我做到了。

def mysort(words):
    mylist1 = sorted([i for i in words if i[:1] == "s"])
    mylist2 = sorted([i for i in words if i[:1] != "s"])
    list = mylist1 + mylist2
    return list

我只是在寻找实现这一目标的替代方法,或者是否有人可以找到上面代码的任何问题。

4

4 回答 4

11

您可以在一行中完成,其中:

sorted(words, key=lambda x: 'a' + x if x.startswith('s') else 'b' + x)

sorted()函数采用关键字参数key,用于在完成比较之前转换列表中的值。

例如:

sorted(words, key=str.lower)
    # Will do a sort that ignores the case, since instead
    # of checking 'A' vs. 'b' it will check str.lower('A')
    # vs. str.lower('b').

sorted(intlist, key=abs)
    # Will sort a list of integers by magnitude, regardless
    # of whether they're negative or positive:
    # >>> sorted([-5,2,1,-8], key=abs)
    #     [1, 2, -5, -8]

我在进行排序时使用了这样的翻译字符串的技巧:

"hello" => "bhello"  
"steve" => "asteve"

所以在比较中“steve”会出现在“hello”之前,因为比较是a/b前缀完成的。

请注意,这只影响用于比较的键,而不影响排序后的数据项。

于 2013-07-12T05:59:02.070 回答
5

1. 你可以generator expression在里面使用sorted

2. 您可以使用str.startswith.

3. 不要list用作变量名。

4. key=str.lower在排序中使用。

mylist1 = sorted((i for i in words if i.startswith(("s","S"))),key=str.lower)
mylist2 = sorted((i for i in words if not i.startswith(("s","S"))),key=str.lower)
return mylist1 + mylist2

为什么str.lower

>>> "abc" > "BCD"
True
>>> "abc" > "BCD".lower()  #fair comparison
False
于 2013-07-12T05:54:03.777 回答
1
>>> l = ['z', 'a', 'b', 's', 'sa', 'sb', '', 'sz']
>>> sorted(l, key=lambda x:(x[0].replace('s','\x01').replace('S','\x01') if x else '') + x[1:])
['', 's', 'sa', 'sb', 'sz', 'a', 'b', 'z']

出于排序的目的,这个键函数替换了以 a开头的每个值,S或者在其他所有内容之前排序。s\x01

于 2013-07-12T05:58:34.100 回答
1

我更喜欢使用元组的答案之一,Integer因为它更干净,也更通用(适用于任意元素,而不仅仅是字符串):

sorted(key=lambda x : ((1 if x[:1] in ("S", "s") else 2), x))

解释:

该参数允许根据 的值而不是根据where is an arbitray 函数的值key对数组进行排序。f(item)itemf

在这种情况下,该函数是匿名的(lambda)并返回一个元组,其中第一个元素是您希望元素结束的“组”(例如,如果字符串以“s”开头,则为 1,否则为 2)。

使用元组是有效的,因为元组比较在元素上是按字典顺序进行的,因此在排序中,组代码的权重将超过元素。

于 2013-07-12T06:29:22.977 回答