Python,如何对字典进行排序

3

我正在处理一个Python字典。我正在尝试按字母顺序对其进行排序,并将其拆分以使其看起来更好一些。以下是我在字典中迄今为止的代码。

authorentry = {'author':  name, 'date': datef , 'path': path_change , 'msg' : xmlMsgf }           
if not name in author:
    author[ name ] = []

author[ name ].append( authorentry )       

if not authorentry in author.items():
    author['author'] = [authorentry]

print sorted (author.keys()), sorted (author.values())

现在我想要的是按照作者和日期的顺序对字典进行排序并打印出来。如果可能的话,将其分割并修改,以便不包含所有那些逗号和'u'。有关如何实现此目标的任何想法吗?
这是当我按原样打印它时它看起来的样子。
我希望作者首先出现在列表中而不是日期。如果可能的话,我希望它按字母顺序排列,并删除条目中的逗号以使其更清晰地打印。是否可能?
[[{'date': ['06-08-2012 09:01:52 PM'], 'path': [u'/branches/Patch_4_2_0_Branch'], 'msg': ['none', u'PATCH_BRANCH:N/A\nBUG_NUMBER:N/A\nFEATURE_AFFECTED:N/A\nOVERVIEW:N/A\nAdding the SVN log size requirement to the branch \n'], 'author': u'glv'}], [{'date': ['06-08-2012 09:01:52 PM'], 'path': [u'/branches/Patch_4_2_0_Branch'], 'msg': ['none', u'PATCH_BRANCH:N/A\nBUG_NUMBER:N/A\nFEATURE_AFFECTED:N/A\nOVERVIEW:N/A\nAdding the SVN log size requirement to the branch \n'], 'author': u'glv'}]]

更新:目前我可以将作者分组,但由于某些原因,我不仅无法按字母顺序排列,甚至无法让作者成为列表中的第一个人,显示出来的内容类似于这样:
 Date: 06-08-2012 08:56:09 PM

  Changes by : glv

  Comments: PATCH_BRANCH:N/A BUG_NUMBER:N/A FEATURE_AFFECTED:N/A OVERVIEW:N/A Adding the svn commit line requrement  

            Directory Location: /trunk

The way i wanted it ordered is more like this.

  Changes by : glv
  Date: 06-08-2012 08:56:09 PM
  Directory Location: /trunk
  Comments: PATCH_BRANCH:N/A BUG_NUMBER:N/A FEATURE_AFFECTED:N/A OVERVIEW:N/A Adding the svn commit line requrement

我尝试使用有序列表来看看是否可以以这种方式使其工作,但迄今为止没有运气或成功。我是否漏掉了什么东西?


1
字典本身是无序的,除非你使用OrderedDict类。 - user2665694
1
你应该意识到u和逗号只是用来显示字典语法的一部分,对吧?你负责按照自己的方式打印元素... 另外 - 我可以看到可能与XML有关联,但它并没有被使用 - 一个单独的字典包含了所有作者姓名等信息... 这会有帮助 - 1)正确格式化你的代码,2)展示示例数据 - Jon Clements
1
你可以考虑使用一个类来代替字典,并实现__str__方法,来处理authorentry - tobias_k
除了字典(dict)之外,你会推荐哪个类?你觉得集合类(collections)怎么样? - Gilbert V
嗯,这只是我被教导的方式,如果你愿意,我可以贴上整个代码。它非常长,不确定是否有帮助。 - Gilbert V
2个回答

2
如果你只关心将这些信息呈现给用户阅读,那么请使用pprint模块。
import pprint
pprint.pprint(author)

假设 author 是一个字典。或者可以使用 pprint.pformat 获取一个字符串,您可以进一步操作/清理,例如 print pprint.pformat(author).replace(',','') 来删除逗号。
您还应该知道,由于字典本质上是哈希表(如集合)的键,因此无法重新排序。
您还可以尝试使用 collections.OrdererdDict:
from collections import OrdererdDict
sorted_author = OrderedDict(sorted(author.iteritems()))

更新:很奇怪你仍然有这个问题。我只会给你一些代码,它一定能够正常工作,然后你可以从那里进行调整:
def format_author(author):
    tups = sorted(author.iteritems())           # alphabetical sorting
    kmaxlen = max([len(k) for k, v in tups])    # for output alignment

    # some custom rearrangement. if there is a 'msg' key, we want it last
    tupkeys = [k for k, v in tups]
    if 'msg' in tupkeys:
        msg_tup = tups.pop(tupkeys.index('msg'))
        tups.append(msg_tup)    # append to the end
        # alternatively tups.insert(0, msg_tup) would insert at front

    output = []

    for k, v in tups:
        # dress our values
        if not v:
            v = ''
        elif isinstance(v, list):
            if len(v) == 1:
                v = v[0]
            if len(v) == 2 and v[0] in [None, 'none', 'None']:
                v = v[1]
         v = v.strip()
        output.append("%s: %s" % (k.rjust(kmaxlen), v))
    return "\n".join(output)

然后你可以像这样做:
author = {'date': ['06-08-2012 09:01:52 PM'], 'path': [u'/branches/Patch_4_2_0_Branch'], 'author': u'glv', 'msg': ['none', u'blah blah blah \n']}
s = format_author(author)
print s

并获得如下输出:
author: glv
  date: 06-08-2012 09:01:52 PM
  path: /branches/Patch_4_2_0_Branch
   msg: blah blah blah

1
@GilbertLeeVera 你使用的是哪个版本的Python? - Preet Kukreti
1
看起来你有嵌套的字典。你仍然可以使用上面的代码,但是你需要为嵌套的输入进行适应。 - Preet Kukreti
1
好吧,我尝试解决这个错误的一种方法是设置#tups = str(sorted(author.iteritems())#看看是否有帮助,但现在我遇到了另一个错误: -kmaxlen = max([len(k) for k, v in tups])-
ValueError: 需要多于1个值来拆包
- Gilbert V
1
@GilbertLeeVera,我上面贴的代码需要是一个键值对的字典。目前它只支持叶级别的字典(即不支持嵌套字典)。它支持我作为示例使用的那种字典。如果你的数据结构有所不同,你将需要调整代码以适应你的需求。但是我上面发布的示例可以处理我在示例中使用的数据。 - Preet Kukreti
1
@GilbertLeeVera tups.insert(0, author_tup)会将其插入到最前面。但是,除非在它前面插入了某些内容,或者它实际上是键的词典顺序中的第二个(可能在第一个键中有前导空格),否则作者不应该出现在第二个位置。 - Preet Kukreti
显示剩余8条评论

1
您可以考虑创建一个 authorentry 类,而不是使用字典并实现 __str__ 方法。
class authorentry:
    # create authorentry; usage: x = authorentry(author, date, path, msg)
    def __init__(self, author, date, path, msg):
        self.author = author
        self.date = date
        self.path = path
        self.msg = msg
    # return string representation for authorentry
    def __str__(self):
        return "Authorentry(name: %s, date: %r, path: ...)" % (self.author, self.date, ...)

现在您可以像这样创建和打印authorentry

ae = authorentry("some name", "some date", "some path", "some message")
print ae

似乎很有趣,我还没有在Python中实际创建过类。我会进行一些研究,看看是否能够实现它并使用它来改进我的代码。谢谢。 - Gilbert V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接