我正按照todo
priority
进行排序
>>> todo
['see doctor', 'do assignment', 'pay rent', 'check bank account', 'clean room']
>>> priority
[3, 4, 1, 2, 5]
>>> todo.sort(key=lambda x: priority[todo.index(x)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
ValueError: 'see doctor' is not in list
为什么在尝试按此类todo
排序时会出现此错误?
可以使用sorted
:
>>> sorted(todo, key=lambda x: priority[todo.index(x)])
['pay rent', 'check bank account', 'see doctor', 'do assignment', 'clean room']
为什么它适用于sorted
但不适用于sort
?
答案 0 :(得分:3)
好吧,您可以简单地zip()
2个列表,然后使用sorted()
在priority
的基础上对其进行排序。
>>> todo = ['see doctor', 'do assignment', 'pay rent', 'check bank account', 'clean room']
>>> priority = [3, 4, 1, 2, 5]
>>> [y for (x,y) in sorted(zip(priority, todo))]
['pay rent', 'check bank account', 'see doctor', 'do assignment', 'clean room']
编辑:您收到错误ValueError: 'see doctor' is not in list
的原因是因为使用list.sort()
和内置函数{{3}之间存在差异}。
sorted()
会返回新排序列表,原始列表不受影响。list.sort()
对列表就地进行排序,改变列表索引。
您可以参考此sorted()
以获得有关差异的更多说明。
如果您引用answer(listsort()
函数),您会注意到函数中的注释 -
该列表暂时为空,因此比较函数执行的突变不会影响我们正在排序的内存片段。
因此,当lambda函数执行时,它会尝试在列表中找到'see doctor'
的索引(来自todo.index(x)
)。但由于列表为空,因此返回ValueError: 'see doctor' is not in list
。
sorted()
不会引发此错误,因为它初始化一个新的空列表,然后将字符串附加到新创建的列表中而不修改给定列表(即todo
)。
答案 1 :(得分:2)
杰森给了你(更好的)解决方案(或者使用numpy并使用numpy数组索引;甚至更简单)。
至于为什么,您会收到错误:您在第一个代码中对todo
就地进行排序;同时,你要求todo
,因此你要求的是一个就地改变的清单。那不是个好主意
sorted()
有效,因为首先制作todo
的副本,并对该副本进行排序,因此仍会在原始.index()
上调用todo
。
numpy:
>>> todo = np.array(todo)
>>> priority = np.array(priority) - 1 # Python is 0-based
>>> todo[priority]
array(['pay rent', 'check bank account', 'see doctor', 'do assignment',
'clean room'], dtype='|S18')
>>> print(todo[priority])
['pay rent' 'check bank account' 'see doctor' 'do assignment' 'clean room']