将列表元素附加到正确的排序位置

时间:2015-02-23 11:29:05

标签: python list sorting python-3.x

我试图获取一个点的给定半径内的玩家列表,并按照它们到该点的距离对它们进行排序。 获得球员很简单:

players = [
    player for player in Player.instances
    if player.distance(my_point) <= max_radius
]

排序也很顺利:

return sorted(players, key=lambda player: player.get_distance(my_point))

然而,如果服务器中充满了玩家,那么为每个人调用player.distance(my_point)可能会变得很重,因此之后对玩家进行排序总是需要一些额外的时间。 有没有办法自动对列表进行排序,同时将玩家附加到其中,所以我不必每次都循环两次并拨打getdistance两次?

2 个答案:

答案 0 :(得分:3)

作为使用排序数据结构(如Martijn Pieters建议)的替代方法,您可以将距离信息与玩家对象组合在一起。您可以通过将其作为属性添加到播放器类,或者通过将每个播放器实例与其距离信息临时组合来实现。例如,

players = []
for player in Player.instances:
    dist = player.distance(my_point)
    if dist <= max_radius:
        players.append((dist, player))

#Sort in order of distance. If two distances match, sort by player.
players.sort()

#Strip out dist info
players = [v for u,v in players]

#or
players = zip(*players)[1]

答案 1 :(得分:2)

如果距离确实是欧几里德空间中的距离,那么您可以使用的是某种空间分割算法,例如2D的quadtree或3D的octree;

如果您有静态集,则不需要空间分区。但是如果你有一个带有许多参考点的动态集,或者玩家正在移动,这些比计算距离(O(kn)距离计算)更有效,然后计算每个参考点的最近值至少{{1}每次计算距离时,操作总计。

另请参阅相关的C++ discussion