按条件标准对列表进行排序

时间:2017-04-28 14:47:03

标签: python list sorting

我知道如何使用sort()方法和适当的lambda规则简单地在Python中对列表进行排序。但是我不知道如何处理以下情况:

  

我有一个字符串列表,它们只包含字母或包含特定的关键字和数字。我想首先对列表进行排序,以便将带有关键字的元素放在最后,然后按照它们包含的数字对它们进行排序。

e.g。我的列表可能是:mylist = ['abc','xyz','keyword 2','def','keyword 1'],我希望它排序为['abc','def','xyz','keyword 1','keyword 2']

我已经有类似

的东西了
mylist.sort(key=lambda x: x.split("keyword")[0],reverse=True)

仅产生

['xyz', 'def', 'abc', 'keyword 2', 'keyword 1']

4 个答案:

答案 0 :(得分:2)

您可以使用不包含关键字的“last”元素作为屏障,先排序不带关键字的单词,然后使用关键字排序:

barrier = max(filter(lambda x: 'keyword' not in x, mylist))
# 'xyz'    

mylist_barriered = [barrier + x if 'keyword' in x else x for x in mylist]
# ['abc', 'xyz', 'xyzkeyword 2', 'def', 'xyzkeyword 1']

res = sorted(mylist_barriered)
# ['abc', 'def', 'xyz', 'xyzkeyword 1', 'xyzkeyword 2']

# Be sure not to replace the barrier itself, `x != barrier`
res = [x.replace(barrier, '') if barrier in x and x != barrier else x for x in res]

res现在是:

['abc', 'def', 'xyz', 'keyword 1', 'keyword 2']

这种非硬编码方法(显然在'keyword'之外)的好处是,您的关键字可以出现在字符串中的任何位置,并且该方法仍然有效。使用['abc', 'def', '1 keyword 2', 'xyz', '1 keyword 4']尝试上述代码,看看我的意思。

另一种简单的方法,采用分而治之的方法:

precedes = [x for x in mylist if 'keyword' not in x]

sort_precedes = sorted(precedes)

follows = [x for x in mylist if 'keyword' in x]

sort_follows = sorted(follows)

together = sort_precedes + sort_follows

together
['abc', 'def', 'xyz', 'keyword 1', 'keyword 2']

答案 1 :(得分:1)

首先检查项目是否以关键字开头,然后对元组进行排序。如果是,则将元组中的第一项设置为1,然后将另一项设置为关键字后面的数字。对于非关键字项,请将第一个元组项设置为0(因此它们始终位于关键字之前),然后另一个元组项可用于字典排序:

def func(x):
   if x.startswith('keyword'):
       return 1, int(x.split()[-1])
   return 0, x

mylist.sort(key=func)
print(mylist)
# ['abc', 'def', 'xyz', 'keyword 1', 'keyword 2']

答案 2 :(得分:1)

单线解决方案:

mylist.sort(key=lambda x: (len(x.split())>1, x if len(x.split())==1 else int(x.split()[-1]) ) )

<强>说明: 第一个条件len(x.split())>1确保多个单词字符串落后于单个字符串,因为它们可能具有数字。因此,现在只有单个字符串与单个字符串之间或由于第一个条件而具有多个字符串的多个字符串之间存在联系。请注意,多字和单字串不会有任何联系。因此,如果多字符串我返回一个整数else返回字符串本身。

示例:

  

['xyz','keyword 1000','def','abc','keyword 2','keyword 1']

结果:

>>> mylist=['xyz', 'keyword 1000', 'def', 'abc', 'keyword 2', 'keyword 1']
>>> mylist.sort(key=lambda x: (len(x.split())>1, x if len(x.split())==1 else int(x.split()[-1]) ) )
>>> mylist
['abc', 'def', 'xyz', 'keyword 1', 'keyword 2', 'keyword 1000']

答案 3 :(得分:0)

我在包含“keyword”的字符串前缀为ascii表中的最高值,因此它们在内置排序函数评估时结束。 https://repl.it/H66r/1

mylist.sort(key=lambda x: x if (x.find("keyword", 0) != -1) else '\127' + x)

编辑: 这不是根据他们的数字对关键字字符串进行排序。 使用元组解决方案,我们可以提出:https://repl.it/H66r/8 如果不包含“keyword”,则元组索引的第一个值非常低,否则为其实际值。让系统对具有相似值的所有键进行排序。

mylist.sort(key=lambda x: (- sys.maxsize, x) if (x.find("keyword", 0) == -1) else (int(x.split(" ")[1]), x) )