如何在python中对轮胎尺寸进行分类

时间:2012-12-27 07:11:18

标签: python list sorting

我正在尝试将(字符串)轮胎尺寸列表从最小到最大排序。

['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嵌套混乱的情况下解决这个问题?

7 个答案:

答案 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.splitreversedtuple的合成来创建用于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)

如果/的位置不变,请尝试:

sorted(a, key=lambda x:x[-2:]+x[4:6]+x[:3])

http://ideone.com/M6X6pW

答案 5 :(得分:0)

    python 3.2

    sorted(list1,key=lambda x:x[-2:])

答案 6 :(得分:0)

这个Q / A给了我指点来解决我自己的问题 - 添加让其他人知道 以这种格式列出* nix目录: /home/0000/Maildir/<0-255>/<userdirs>

<00> 0000 - 四位数的唯一提供商名称
&LT; 0-255&GT; - 范围

列表大小从3000到250000不等。

我需要在第四个字段中使用数字排序对列表进行排序,在每个项目中用“/”分隔

sorted(a, key=lambda y: int(y.split("/")[4]))