我想根据第二个列表对列表进行排序,如 this堆栈溢出帖子。
就我而言,我的代码试图对 Chromo
进行排序对象对应的 fitness_weights
,所以我尝试了链接帖子中的解决方案:
def foobar():
...
chromolist = [x for _, x in sorted(zip(fitness_weights, chromolist))]
...
报错:
TypeError: '<' not supported between instances of 'Chromo' and 'Chromo'
为了调试我试过:
def foobar():
...
try:
chromolist = [x for _, x in sorted(zip(fitness_weights, chromolist))]
except Exception as e:
print(fitness_weights)
print(chromolist)
print([i for i in zip(fitness_weights, chromolist)])
raise e
print('works fine')
...
输出:
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
works fine
[2630793242, 2662598634, 1204127226, 1218205610, 1224753838, 1212750850,
1212293610, 1221507266, 1269226518, 1363578674, 1209661338, 2674408754,
1179213986, 1209887778, 2281636710, 1906925334, 1156258126, 1287144442,
1218205610, 1256241498, 2926198286, 1533442630, 1587421406, 2685579290,
1203563674, 1205066274, 1181576990, 1188462746, 1127834446, 2295554650,
1216261042, 1193222146, 1191591394, 1206052810, 1206800842, 1213410890,
1202786310, 1230097202, 1277296358, 1218982810]
[Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object,
Chromo Object, Chromo Object, Chromo Object, Chromo Object, Chromo Object]
[(2630793242, Chromo Object), (2662598634, Chromo Object),
(1204127226, Chromo Object), (1218205610, Chromo Object),
(1224753838, Chromo Object), (1212750850, Chromo Object),
(1212293610, Chrom Object), (1221507266, Chromo Object),
(1269226518, Chromo Object), (1363578674, Chromo Object),
(1209661338, Chromo Object), (2674408754, Chromo Object),
(1179213986, Chromo Object), (1209887778, Chromo Object),
(2281636710, Chromo Object), (1906925334, Chromo Object),
(1156258126, Chromo Object), (1287144442, Chromo Object),
(1218205610, Chromo Object), (1256241498, Chromo Object),
(2926198286, Chromo Object), (1533442630, Chromo Object),
(1587421406, Chromo Object), (2685579290, Chromo Object),
(1203563674, Chromo Object), (1205066274, Chromo Object),
(1181576990, Chromo Object), (1188462746, Chromo Object),
(1127834446, Chromo Object), (2295554650, Chromo Object),
(1216261042, Chromo Object), (1193222146, Chromo Object),
(1191591394, Chromo Object), (1206052810, Chromo Object),
(1206800842, Chromo Object), (1213410890, Chromo Object),
(1202786310, Chromo Object), (1230097202, Chromo Object),
(1277296358, Chromo Object), (1218982810, Chromo Object)]
这是令人困惑的,因为:
- 所有数据类型都正确
- 该功能正确运行了 22 次li>
我该如何解决这个问题?
最佳答案
当您有两个具有相等权重的 (weight, chromo)
对时会发生错误,此时 Python 会尝试比较 chromo
值:
>>> class Chromo:
... pass
...
>>> chromolist = [Chromo(), Chromo()]
>>> fitness_weights = [42, 42]
>>> sorted(zip(fitness_weights, chromolist))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'Chromo' and 'Chromo'
您可以通过使用仅提取权重的自定义排序键或添加对排序序列中的每个值都是唯一的决胜局(例如计数器)来避免此问题:
from itertools import count
chromolist = [x for *_, x in sorted(zip(fitness_weights, count(), chromolist))]
计数器只是为了确保 Python 永远不会查看 Chromo
实例,因为现在每个元素都是一个 (weight, unique_integer, Chromo)
元组:
>>> from itertools import count
>>> sorted(zip(fitness_weights, count(), chromolist))
[(42, 0, <__main__.Chromo object at 0x1038cfa00>), (42, 1, <__main__.Chromo object at 0x103a396d0>)]
排序键只是一个生成要比较的值的函数,您可以使用 lambda (lambda t: t[0]
) 或 operator.itemgetter()
object :
from operator import itemgetter
chromolist = [x for _, x in sorted(zip(fitness_weights, chromolist), key=itemgetter(0))]
key 函数需要单独传递输入列表,因此速度稍慢,如这个具有 200 个输入的简单时间试验所示:
>>> from timeit import timeit
>>> fw = fitness_weights * 100
>>> cl = chromolist * 100
>>> timeit('sorted(zip(fw, count(), cl))', globals=globals(), number=100000)
1.4618491119981627
>>> timeit('sorted(zip(fw, cl), key=itemgetter(0))', globals=globals(), number=100000)
1.6409574589997646
关于python - 使用 zip() 对元组列表进行排序时,有时不支持“<”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61646046/