Python排序问题

发布于 2024-09-11 09:53:18 字数 541 浏览 6 评论 0原文

我需要在Python中对以下元组列表进行排序:

ListOfTuples = [('10', '2010 Jan 1;', 'Rapoport AM', 'Role of antiepileptic drugs as preventive agents for migraine', '20030417'), ('21', '2009 Nov;', 'Johannessen SI', 'Antiepilepticdrugs in epilepsy and other disorders--a population-based study of prescriptions', '19679449'),...]

我的目的是按降序年份(listOfTuples[2])和升序作者(listOfTuples[2])排序):

sorted(result, key = lambda item: (item[1], item[2]))

但这不起作用。如何获得排序稳定性?

i need to sort the following list of Tuples in Python:

ListOfTuples = [('10', '2010 Jan 1;', 'Rapoport AM', 'Role of antiepileptic drugs as preventive agents for migraine', '20030417'), ('21', '2009 Nov;', 'Johannessen SI', 'Antiepilepticdrugs in epilepsy and other disorders--a population-based study of prescriptions', '19679449'),...]

My purpose is to order it by Descending year (listOfTuples[2]) and by Ascending Author (listOfTuples[2]):

sorted(result, key = lambda item: (item[1], item[2]))

But it doesn't work. How can i obtain sort stability?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

纸短情长 2024-09-18 09:53:18
def descyear_ascauth(atup):
  datestr = atup[1]
  authstr = atup[2]
  year = int(datestr.split(None, 1)[0])
  return -year, authstr

... sorted(result, key=descyear_ascauth) ...

注意:您需要将年份提取为整数(而不是字符串),以便您可以更改其符号 - 后者是满足规范“降序”部分的关键技巧。将所有内容压缩到 lambda 中是可能的,但是绝对没有理由这样做并牺牲更多的可读性,因为 def 也可以正常工作(而且更多)可读)。

def descyear_ascauth(atup):
  datestr = atup[1]
  authstr = atup[2]
  year = int(datestr.split(None, 1)[0])
  return -year, authstr

... sorted(result, key=descyear_ascauth) ...

Notes: you need to extract the year as an integer (not as a string), so that you can change its sign -- the latter being the key trick in order to satisfy the "descending" part of the specifications. Squeezing it all within a lambda would be possible, but there's absolutely no reason to do so and sacrifice even more readability, when a def will work just as well (and far more readably).

盗心人 2024-09-18 09:53:18

最简单的方法是分别对每个键值进行排序。从最不重要的键开始,一直到最重要的键。

所以在这种情况下:

import operator
ListOfTuples.sort(key=operator.itemgetter(2))
ListOfTuples.sort(key=lambda x: x[1][:4], reverse=True)

这是有效的,因为即使你使用反向标志,Python 的排序也总是稳定的:即反向不只是排序然后反向(这会失去稳定性,它在反向后保持稳定性。

当然,如果你有很多对于关键列,这可能效率很低,因为它会多次进行完整排序。

您不必以这种方式将年份转换为数字,因为它是真正的反向排序,但如果您愿意,也可以这样做。

The easiest way is to sort on each key value separately. Start at the least significant key and work your way up to the most significant.

So in this case:

import operator
ListOfTuples.sort(key=operator.itemgetter(2))
ListOfTuples.sort(key=lambda x: x[1][:4], reverse=True)

This works because Python's sorting is always stable even when you use the reverse flag: i.e. reverse doesn't just sort and then reverse (which would lose stability, it preserves stability after reversing.

Of course if you have a lot of key columns this can be inefficient as it does a full sort several times.

You don't have to convert the year to a number this way as its a genuine reverse sort, though you could if you wanted.

白首有我共你 2024-09-18 09:53:18

这是一个适用于所有事物的习惯用法,甚至是你无法否定的事物,例如字符串:

data = [ ('a', 'a'), ('a', 'b'), ('b','a') ]

def sort_func( a, b ):
    # compare tuples with the 2nd entry switched
    # this inverts the sorting on the 2nd entry
    return cmp( (a[0], b[1]), (b[0], a[1]) ) 

print sorted( data )                    # [('a', 'a'), ('a', 'b'), ('b', 'a')]
print sorted( data, cmp=sort_func )     # [('a', 'b'), ('a', 'a'), ('b', 'a')]

Here is a idiom that works for everything, even thing you can't negate, for example strings:

data = [ ('a', 'a'), ('a', 'b'), ('b','a') ]

def sort_func( a, b ):
    # compare tuples with the 2nd entry switched
    # this inverts the sorting on the 2nd entry
    return cmp( (a[0], b[1]), (b[0], a[1]) ) 

print sorted( data )                    # [('a', 'a'), ('a', 'b'), ('b', 'a')]
print sorted( data, cmp=sort_func )     # [('a', 'b'), ('a', 'a'), ('b', 'a')]
一梦等七年七年为一梦 2024-09-18 09:53:18

这是一个粗略的解决方案,需要考虑月份缩写和日期(如果找到):

import time
import operator

def sortkey(seq):
    strdate, author = seq[1], seq[2]
    spdate = strdate[:-1].split()
    month = time.strptime(spdate[1], "%b").tm_mon
    date = [int(spdate[0]), month] + map(int, spdate[2:])
    return map(operator.neg, date), author  

print sorted(result, key=sortkey)

“%b”是语言环境的缩写月份名称,如果您不想处理语言环境,可以使用字典。

Here's a rough solution that takes month abbreviature and day (if found) in account:

import time
import operator

def sortkey(seq):
    strdate, author = seq[1], seq[2]
    spdate = strdate[:-1].split()
    month = time.strptime(spdate[1], "%b").tm_mon
    date = [int(spdate[0]), month] + map(int, spdate[2:])
    return map(operator.neg, date), author  

print sorted(result, key=sortkey)

"%b" is locale's abbreviated month name, you can use a dictionary if you prefer not to deal with locales.

原谅我要高飞 2024-09-18 09:53:18

这是 Alex 答案的 lambda 版本。我认为它现在看起来比邓肯的答案更紧凑,但显然亚历克斯的答案已经失去了很多可读性。

sorted(ListOfTuples, key=lambda atup: (-int(atup[1].split(None, 1)[0]), atup[2]))

可读性和效率通常应该优先于紧凑性。

Here is the lambda version of Alex's answer. I think it looks more compact than Duncan's answer now, but obviously a lot of the readability of Alex's answer has been lost.

sorted(ListOfTuples, key=lambda atup: (-int(atup[1].split(None, 1)[0]), atup[2]))

Readability and efficiency should usually be preferred to compactness.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文