我应该拿一个单词列表并对其进行排序,除了我需要先将所有以'x'开头的字符串分组。
这是我得到的:
list_1 = []
list_2 = []
for word in words:
list_1.append(word) if word[0] == 'x' else list_2.append(word)
return sorted(list_1) + sorted(list_2)
但我觉得有一种更优雅的方式可以做到这一点......
修改
实施例:
['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
会产生['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
。
答案 0 :(得分:41)
>>> words = ['xoo', 'dsd', 'xdd']
>>> sorted(words, key=lambda x: (x[0] != 'x', x))
['xdd', 'xoo', 'dsd']
说明:key函数返回一对(元组)。第一个元素是False
或True
,具体取决于字符串中的第一个字符是'x'
。 False
在True
之前排序,因此以'x'
开头的字符串将在排序输出中排在第一位。元组中的第二个元素将用于比较第一个元素中相同的两个元素,因此所有以'x'
开头的字符串将在它们之间进行排序,并且所有字符串不以{{1}开头将在他们自己之间进行分类。
答案 1 :(得分:9)
首先:当你的意思是“干净”时,不要再说“pythonic”了。这只是一个俗气的流行词。
不要使用那样的三元表达;它意味着用作表达式的一部分,而不是用作流控制。这更清洁:
for word in words:
if word[0] == 'x':
list_1.append(word)
else:
list_2.append(word)
你可以多改进一下 - 使用像这样的三元表达式很好:
for word in words:
target = list_1 if word[0] == 'x' else list_2
target.append(word)
如果words
是容器而不是迭代器,则可以使用:
list_1 = [word for word in words if word[0] == 'x']
list_2 = [word for word in words if word[0] != 'x']
最后,我们可以废弃整件事,而是使用两种:
result = sorted(words)
result = sorted(result, key=lambda word: word[0] != 'x')
首先进行正常排序,然后使用Python排序的稳定属性将以“x”开头的单词移到前面,而不会改变排序。
答案 2 :(得分:6)
words = ['xoo', 'dsd', 'xdd']
list1 = [word for word in words if word[0] == 'x']
list2 = [word for word in words if word[0] != 'x']
答案 3 :(得分:5)
应该注意的是,在Python 2.4中添加了sorted
。如果您希望更短的版本更清晰,更向后兼容,您也可以直接使用.sort()
功能list
。 还应该注意,在这种情况下使用x[0]
样式数组索引语法时,空字符串将引发异常(正如许多示例所示)。 .startswith()
should be used instead, as is properly used in Tony Veijalainen's answer。
>>> words = ['mix', 'xyz', '', 'apple', 'xanadu', 'aardvark']
>>> words.sort(key=lambda x: (not x.startswith('x'), x))
>>> words
['xanadu', 'xyz', '', 'aardvark', 'apple', 'mix']
唯一的缺点是你正在改变给定的对象。这可以通过预先切片列表来解决。
>>> words = ['mix', 'xyz', '', 'apple', 'xanadu', 'aardvark']
>>> new_words = words[:]
>>> new_words.sort(key=lambda x: (not x.startswith('x'), x))
>>> new_words
['xanadu', 'xyz', '', 'aardvark', 'apple', 'mix']
>>> words
['mix', 'xyz', '', 'apple', 'xanadu', 'aardvark']
答案 4 :(得分:2)
words = ['xoo', 'dsd', 'xdd']
list1=filter(lambda word:word[0]=='x',words)
list2=filter(lambda word:word[0]!='x',words)
答案 5 :(得分:2)
重新发送变体SilenGhosts代码(随意复制,SilentGhost)作为代码而不是命令提示符日志
notinorder = ['mix', 'xyz', '', 'apple', 'xanadu', 'aardvark']
print sorted(notinorder, key = lambda x: (not x.startswith('x'), x))
答案 6 :(得分:1)
>>> x = ['abc', 'xyz', 'bcd', 'xabc']
>>> y = [ele for ele in x if ele.startswith('x')]
>>> y
['xyz', 'xabc']
>>> z = [ele for ele in x if not ele.startswith('x')]
>>> z
['abc', 'bcd']
答案 7 :(得分:0)
更多原始解决方案:
l1=[] l2=[] for w in sorted(words): (l1 if w[0] == 'x' else l2).append(w) l1.extend(l2) return l1