我需要根据另一个列表中元素的顺序对列表进行排序,该列表更短,即与我正在排序的列表相比,没有所有元素。使用sort(key=short_list)
时遇到此错误:
long_list = ['y', 'z', 'x', 'c', 'a', 'b']
short_list = ['b', 'c', 'a']
long_list.sort(key=short_list.index)
ValueError: 'x' is not in list
是否还有另一种方式对long_list
进行排序,以使list
保持short_list
的顺序,然后保持long_list
中元素的顺序? / p>
['b', 'c', 'a', 'y', 'z', 'x']
答案 0 :(得分:5)
类似的事情应该起作用:
def position(value):
try:
return short_list.index(value)
except ValueError:
return len(short_list)
long_list.sort(key=position)
Sorting is guaranteed to be stable,因此使用len(short_list)
可确保未知值排在最后。
答案 1 :(得分:3)
您可以使用in
来检测元素是否在short_list中,并使用三进制来返回基于该元素的元组。
>>> long_list = ['y', 'z', 'x', 'c', 'a', 'b']
>>> short_list = ['b', 'c', 'a']
>>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list else (len(short_list),e))
['b', 'c', 'a', 'x', 'y', 'z']
由于Python排序稳定,因此顺序只会根据元素本身的变化而变化。要进行更改,我们可以使用具有(index_of_the_element, element)
中的(len(short_list), element)
的元组来实现该更改。
如果您希望元素不在短列表中而不改变顺序,只需返回一个空元组:
>>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list else (len(short_list),))
['b', 'c', 'a', 'y', 'z', 'x']
答案 2 :(得分:2)
如果需要,我会先在短列表中搜索,然后在长列表中搜索:
>>> def index(list1, list2):
... def inner(value):
... try:
... return list1.index(value)
... except ValueError:
... return list2.index(value)
...
>>> long_list = ['x', 'y', 'z', 'a', 'b', 'c']
>>> short_list = ['a', 'b', 'c']
>>> long_list.sort(key=index(short_list, long_list))
>>> long_list
['a', 'b', 'c', 'x', 'y', 'z']
编辑:作为florian-weimer pointed out,此解决方案并不总是有效。加入两个解决方案:
>>> def index(list1, list2):
... def inner(value, l=len(list1)):
... try:
... return list1.index(value)
... except ValueError:
... return l
... return inner
...
>>> long_list = ['x', 'y', 'z', 'a', 'b', 'c']
>>> short_list = ['a', 'b', 'c', 'y']
>>> sorted(long_list, key=index(short_list, long_list))
['a', 'b', 'c', 'y', 'x', 'z']
>>>
答案 3 :(得分:0)
基本上,我在这里做的是首先按 long_list 中的索引对 long_list 的元素进行排序。如果该元素不在 short_list 中,我将为它们分配与 len(short_list) 相同的值。排序时,如果两个元素的 first_sort 相同,则按照 long_list 中的位置 second_sort 进行排序。 让我们看看每个案例
关键要点:
long_list = ['y', 'z', 'x', 'c', 'a', 'b']
short_list = ['b', 'c', 'a']
def sorter(x):
if x in short_list:
first_sort = short_list.index(x)
else:
first_sort = len(short_list)
second_sort = long_list.index(x)
return first_sort, second_sort
print(sorted(long_list, key=sorter))
['b', 'c', 'a', 'y', 'z', 'x']