我正在尝试将(字符串)轮胎尺寸列表从最小到最大排序。
['285/30/18',
'285/30/19',
'235/40/17',
'315/25/19',
'275/30/19']
应排序为:
['235/40/17',
'285/30/18',
'315/25/19'
'275/30/19',
'285/30/19']
我基本上必须从右边,中间然后左边开始排序字符串。
到目前为止(泡泡排序):
# this sorts the first numbers on the right.
nums = list(ulst)
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if ulst[j].split('/')[2] < ulst[i].split('/')[2]:
ulst[j], ulst[i] = ulst[i], ulst[j]
我现在必须对中间进行排序,而不会弄乱右行的排序,然后对左行进行排序....
如何在不创建for / if嵌套混乱的情况下解决这个问题?
答案 0 :(得分:10)
Python有几个功能,使这很容易做到。事实上,你可以在一个声明中完成所有这些:
sorted(nums, key=lambda x: tuple(reversed(list(map(int, x.split("/"))))))
x.split("/")
获取每个值并生成字符串列表:
["235", "40", "17"]
使用map(int, ...)
给出一个整数列表:
[235, 40, 17]
reversed()
转过身来:
[17, 40, 235]
和tuple()
将其转换为元组:
(17, 40, 235)
,与其他类似的元组相比,它给出了你想要的排序顺序。
答案 1 :(得分:1)
一种方法是使用以下value
函数构造排序键,该函数以正确的顺序考虑三个字段:
def value(s):
arr = s.split('/')
return arr[2] * 100000 + arr[1] * 1000 + arr[0]
ulst = ['285/30/18', '285/30/19', '235/40/17', '315/25/19', '275/30/19']
for i in range(len(ulst)):
for j in range(i+1, len(ulst)):
if value(ulst[j]) < value(ulst[i]):
ulst[j], ulst[i] = ulst[i], ulst[j]
print ulst
根据需要输出:
['235/40/17', '285/30/18', '315/25/19', '275/30/19', '285/30/19']
如果您的轮胎尺寸是指定的3/2/2位数,这是一个相当安全的选择,这将正常工作 - 我从未见过12英寸以下的轮胎,100英寸中的一个可能太大而无法骑行: - )
答案 2 :(得分:1)
使用str.split
,reversed
和tuple
的合成来创建用于sorted
的关键功能:
sizes = ['285/30/18',
'285/30/19',
'235/40/17',
'315/25/19',
'275/30/19']
s = sorted(sizes, key=lambda z: tuple(reversed([int(i) for i in z.split("/")])))
排序函数接受序列和键函数,并返回序列项的列表,该列表按列表中每个项的键函数的返回值排序。这个键函数lambda z
首先在“/”字符上拆分项目以给出一个字符串列表,然后将每个字符串转换为数字,然后将这些字符串传递给reversed
函数,该函数给出了传入的序列的反向顺序的迭代器(注意:这尚未评估),tuple
函数计算反向迭代器,将其转换为可用于排序的序列。
所以格式化为“a / b / c”的字符串序列将按(c,b,a)排序返回。这导致:
>>> print s
['235/40/17', '285/30/18', '315/25/19', '275/30/19', '285/30/19']
答案 3 :(得分:1)
很多好的答案。如果你这样做仅仅是为了清酒或快速一次解析,或者是家庭作业,那么他们都说明字符串处理/排序好。但如果你真的在轮胎管理方面建立一个真正的应用程序,我会考虑为你的轮胎制作一个真正的轮胎模型:
from ast import literal_eval
from operator import attrgetter
# Make a real object, because we can, and it's easy, and a real object is almost always better than abusing literal types
class Tire(object):
def __init__(self, width = 0, profile = 0, radius = 0): #now we have meaningful names to our indexed fields
self.width = width
self.profile = profile
self.radius = radius
# let's encapsulate the '{width}/{profile}/{radius}' string representation
# as an attribute so we can access/set it like the "real" attributes
@property
def description(self):
return '{}/{}/{}'.format(self.width, self.profile, self.radius)
@description.setter
def description(self, string):
self.width, self.profile, self.radius = map(literal_eval, string.split('/')) #ast.literal_eval() is safer than just eval()
# let's make a class side instance creation method that can instantiate and set the description directly too
@classmethod
def fromDescription(me, descriptionString):
newTire = me()
newTire.description = descriptionString
return newTire
#your original sample input
descriptions = ['285/30/18', '285/30/19', '235/40/17', '315/25/19', '275/30/19']
#now lets make some real tire objects from those
tires = [Tire.fromDescription(each) for each in descriptions]
#make sure they still print
[print(each.description) for each in tires]
print('original sort')
[print(each.description) for each in sorted(tires, key = attrgetter('radius'))]
print('reversed original sort')
[print(each.description) for each in sorted(tires, key = attrgetter('radius'), reverse = True)]
print('width sort')
[print(each.description) for each in sorted(tires, key = attrgetter('width'), reverse = True)]
print('radius>>width>>profile sort')
[print(each.description) for each in sorted(tires, key = attrgetter('radius', 'width', 'profile'))]
这种方法的价值最终有望显而易见。我们预先支付更高的价格(在代码空间方面)以更新轮胎对象。但是一旦我们拥有了,我们就可以开始疯狂地对它们进行各种分类。在给定字符串表示和所需排序输出的某些假设的情况下,所呈现的算法最初工作得很好。但是如果你需要改变你的排序输出,按照最后一行(按字段3,1,2排序),那么元组上的方便反向技巧将不再起作用。将(它是什么)与你将如何呈现(排序)它分开是更好的(IMO)。在那之后你可能会想到一些更聪明的事情,而不仅仅是对它们进行排序。
答案 4 :(得分:0)
答案 5 :(得分:0)
python 3.2
sorted(list1,key=lambda x:x[-2:])
答案 6 :(得分:0)
这个Q / A给了我指点来解决我自己的问题 - 添加让其他人知道
以这种格式列出* nix目录:
/home/0000/Maildir/<0-255>/<userdirs>
列表大小从3000到250000不等。
我需要在第四个字段中使用数字排序对列表进行排序,在每个项目中用“/”分隔
sorted(a, key=lambda y: int(y.split("/")[4]))