我无法使用.sort()或sorted()来获取此代码以对对象列表进行排序。我在这里缺少什么?
P.S。如果有人有任何建议,我的solution.distance()方法也可以使用一些整容手术。
谢谢!
import random
import math
POPULATION_SIZE = 100
data = [[1, 565.0, 575.0],
[2, 25.0, 185.0],
[3, 345.0, 750.0],
[4, 945.0, 685.0],
[5, 845.0, 655.0],
[6, 880.0, 660.0],
[7, 25.0, 230.0],
[8, 525.0, 1000.0],
[9, 580.0, 1175.0],
[10, 650.0, 1130.0]
]
class Solution():
def __init__(self):
self.dna = []
self.randomize()
def randomize(self):
temp = data[:]
while len(temp) > 0:
self.dna.append( temp.pop( random.randint( 0,len(temp)-1 ) ) )
def distance(self):
total = 0
#There has to be a better way to access two adjacent elements.
for i, points in enumerate(self.dna):
if i < (len(self.dna)-1):
total += math.sqrt( (points[1]-self.dna[i+1][1])**2 + (points[2]-self.dna[i+1][2])**2 )
else:
total += math.sqrt( (points[1]-self.dna[0][1])**2 + (points[2]-self.dna[0][2])**2 )
return int(total)
class Population():
def __init__(self):
self.solutions = []
self.generation = 0
#Populate with solutions
self.solutions = [Solution() for i in range(POPULATION_SIZE)]
def __str__(self):
result = ''
#This is the part that is not returning sorted results. I tried sorted() too.
self.solutions.sort(key=lambda solution: solution.distance, reverse=True)
for solution in self.solutions:
result += 'ID: %s - Distance: %s\n' % ( id(solution), solution.distance() )
return result
if __name__ == '__main__':
p = Population()
print p
答案 0 :(得分:3)
更改
key=lambda solution: solution.distance
到
key=lambda solution: solution.distance()
(需要括号来调用该函数。)
或者,您可以将distance
方法设为属性:
@property
def distance(self):
....
在这种情况下,请将solution.distance()
的所有出现更改为solution.distance
。我认为这种替代解决方案更好一点,因为每次你想谈论距离时,它都会删除两个混乱的字符(parens)。
PS。 key=lambda solution: solution.distance
正在为solution.distance
中的每个solution
返回绑定方法self.solutions
。由于返回相同的对象作为每个solution
的键,因此没有发生所需的排序。
答案 1 :(得分:1)
以下是使用函数式编程技术清理课程的尝试:
import random
class Solution():
def __init__(self):
self.dna = []
self.randomize()
def randomize(self):
self.dna = data
random.shuffle(self.dna)
def distance(self):
# Return the distance between two points.
def point_distance((p1, p2)):
return math.sqrt((p1[1]-p2[1])**2) + (p1[2]-p2[2])**2)
# sums the distances between consecutive points.
# zip pairs consecutive points together, wrapping around at end.
return int(sum(map(point_distance, zip(self.dna, self.dna[1:]+self.dna[0:1])))
这是未经测试的,但应该接近工作。此外,建议使用类而不是3元素列表作为数据。它将使您的代码更清晰易读:
def point_distance((p1, p2)):
return math.sqrt((p1.x-p2.x)**2) + (p1.y-p2.y)**2)
答案 2 :(得分:1)
这是在distance()
中编写循环的更好方法:在代码中添加以下函数定义,取自itertools documentation:
from itertools import izip, tee
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return izip(a, b)
然后你可以编写distance
来利用Python的高效迭代器操作例程,如下所示:
from itertools import chain, islice
def distance(self):
all_pairs = islice(pairwise(chain(self.dna, self.dna)), 0, len(self.dna))
return sum(math.sqrt((p[1]-q[1])**2 + (p[2]-q[2])**2) for p,q in all_pairs)
即使dna
数组很长,这也应该相当有效。