2017-07-07 39 views
0

我的排序方法有问题。python3按attr排序对象列表相同的值

这是包含在列表我的对象: 地址类,随着城市属性

我的目录looklike(简体):

[Address('Paris'), Address('Denver'), Address('Paris'), Address('Test'), Address('Denver')] 

在这个例子中,我有两个重复的城市:巴黎和丹佛,

我想有这样的结果:

[Address('Devenr'), Address('Denver'), Address('Paris'), Address('Paris'), Address('Test')] 

按重复计数排序,如果数字相同,则按字母数字顺序排序。

我想:

self.dictionnary.sort(key=lambda address: len([x for x in self.dictionnary if address.city == x.city])) 

通过这个不工作...

谁能帮助我?

预先感谢您!

回答

1
import collections 
counts = collections.Counter(address.city for address in self.dictionnary) 
self.dictionnary.sort(key=lambda address: (-counts[address.city], address.city)) 

通过使用Counter算在单独的步骤重复的,您将每个你需要一个新的关键时期扫描列表的开销。这对长列表的运行时间会产生很大的影响。关键然后成为一个元组;通过计数的负数,更大的计数将首先按照排序顺序排列。只有当计数相等时,才会考虑元组的第二部分,即城市名称本身。

+0

请问downvoter能解释一下自己吗?我只是检查了这个代码,它完美的工作。再加上它比每次需要新密钥时计算整个列表更有效率。 –

+1

我可以看出为什么有人可能会低估这一点:这是一个只有代码的答案。一般来说,[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高您的帖子的质量。 – vaultah

+0

@vaultah对我来说值得评论,而不是downvote。我为自己确实不正确的事情预留了我的赞誉。 –

1

问题是,巴黎和丹佛都有计数2,所以他们没有得到排序。

如果将字符串添加到排序,以便关系正词法打破它应该工作

例子:

from collections import Counter 

l = ['a', 'b', 'a', 'b', 'c'] 
c = Counter(l) 
l.sort(key=lambda x : -c[x]) 
# l is unchanged 
l.sort(key=lambda x : (-c[x],x)) 
# l is ['a', 'a', 'b', 'b', 'c'] 

编辑:马克的解决方案使用计数器比诉说着每一次好得多。我要去偷那个想法