Eco*_*tle 0 python sorting python-3.x
class City:
def __init__(self, string):
self._string = string.split(',')
self._name = self._string[0]
self._state = self._string[1]
self._latitude = self._string[2]
self._longitude = self._string[3]
self._location = [self._latitude, self._longitude]
def name(self):
return self._name
def location(self):
return self._location
self.hand.sort(key=lambda x: x.longitude)
def __lt__(self, other):
if self._longitude < other._longitude:
return True
if self._longitude > other._longitude:
return False
if self._longitude == other._longitude:
if self._latitude < other._latitude:
return True
if self._latitude > other._latitude:
return False
citystrings = ["Charleston,WV,38.35,81.63",
"Charlotte,NC,35.23,80.83",
"Cheyenne,WY,41.15,104.87",
"Chicago,IL,41.83,87.62",
"Cincinnati,OH,39.13,84.50",
"Cleveland,OH,41.47,81.62",
"Columbia,SC,34.00,81.03",
"Columbus,OH,40.00,83.02",
"Dallas,TX,32.77,96.77",
"Denver,CO,39.75,105.00"]
westtoeastnames = [
"Denver",
"Cheyenne",
"Dallas",
"Chicago",
"Cincinnati",
"Columbus",
"Charleston",
"Cleveland",
"Columbia",
"Charlotte",
]
cities = [City(s) for s in citystrings]
cities.sort()
sortednames = [c.name() for c in cities]
print(sortednames)
print(westtoeastnames)
['Cheyenne', 'Denver', 'Charlotte', 'Columbia', 'Cleveland', 'Charleston', 'Columbus', 'Cincinnati', 'Chicago', 'Dallas']
['Denver', 'Cheyenne', 'Dallas', 'Chicago', 'Cincinnati', 'Columbus', 'Charleston', 'Cleveland', 'Columbia', 'Charlotte']
Run Code Online (Sandbox Code Playgroud)
这段代码试图用它__lt__()来对城市进行排序,以确定它们在西边的距离以及经度位于本初子午线以西的经度.我__lt__()在类中编写了一个方法,但citystrings不会排序到正确的顺序.
您将经度和纬度比较为字符串,而不是数字.因此,它们按字典顺序进行比较,而不是数字进行比较,因此'104'将在 之前进行排序,'80'因为'1'它出现'8'在ASCII表之前(跟随其他字符无关紧要).
将值转换为浮点数:
self._latitude = float(self._string[2])
self._longitude = float(self._string[3])
Run Code Online (Sandbox Code Playgroud)
你的比较有一个小错误; 如果经度和纬度都匹配,则返回None而不是False.您可能希望测试相等性并应用@functools.total_ordering()装饰器而不是假设仅__lt__()调用它.
稍微清理代码(并删除name()和location()方法,只使用name和location属性):
from functools import total_ordering
@total_ordering
class City:
def __init__(self, string):
self.name, self.state, lat, long = string.split(',')
self.location = (self._latitude, self._longitude) = float(lat), float(long)
def __lt__(self, other):
if not isinstance(other, City):
return NotImplemented
# tuples defer ordering to the contents; compare them
# in (longitude, latitude) order so that if longitude is
# equal, the outcome is based on latitude.
return self.location[::-1] < other.location[::-1]
def __eq__(self, other):
if not isinstance(other, City):
return NotImplemented
return self.location == other.location
Run Code Online (Sandbox Code Playgroud)
注意,__lt__()真的只需要比较self.location; 元组排序负责其余的事情:
sortednames = [c.name for c in sorted(map(City, citystrings), reverse=True)]
Run Code Online (Sandbox Code Playgroud)
注意reverse=True; 你希望首先列出较大的值(格林威治西部).
| 归档时间: |
|
| 查看次数: |
106 次 |
| 最近记录: |