使用关键参数列出排序错误

时间:2016-01-11 05:29:53

标签: python python-2.7

我正按照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

2 个答案:

答案 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()以获得有关差异的更多说明。

如果您引用answerlistsort()函数),您会注意到函数中的注释 -

  

该列表暂时为空,因此比较函数执行的突变不会影响我们正在排序的内存片段。

因此,当lambda函数执行时,它会尝试在列表中找到'see doctor'的索引(来自todo.index(x))。但由于列表为空,因此返回ValueError: 'see doctor' is not in list

sorted()不会引发此错误,因为它初始化一个新的空列表,然后将字符串附加到新创建的列表中而不修改给定列表(即todo)。

source code for list.sort()list.sort()的源代码。

答案 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']