【问题标题】:Sort a dict by its value pairs按值对对字典进行排序
【发布时间】:2014-02-10 11:53:15
【问题描述】:

我有一个看起来像这样的字典:

未分类:

12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8  {89 302} 55 {44 301}

我想这样排序:

55 {44 301} 27 {301 302} 8  {89 302} 29 {89 12} 12 {12 489} 26 {489 329}

如您所见,大多数情况下,前一个条目的第二个键值与后一个条目的第一个键值相同。 (12489 在最后两个条目中)

这虽然不是必需的。第二个和第三个条目的302 也满足了“链”的要求,因为它同时存在于第二个和第三个条目中。

我唯一想做的就是对这些条目进行排序,使大括号中的值形成一个不间断的链。

结果看起来像示例中的还是镜像的都没有关系。

从 TCL 8.6 开始,我可以使用 stride 执行类似于 Sort Tcl dict by value 的操作。但我坚持使用这个(Tcl8.5.9)版本。最简单的方法是什么?

【问题讨论】:

    标签: sorting dictionary tcl


    【解决方案1】:

    我不知道这是不是最简单的方法:

    set x [dict create 12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301}]
    
    # transform the dict into a list of lists
    dict for {k v} $x {lappend unsorted [list $k $v]}
    lappend sorted [lindex $unsorted 0]
    set unsorted [lrange $unsorted 1 end]
    
    # keep going until there's nothing more to add to the sorted list
    while {[llength $unsorted] != 0} {
        set changed false
    
        for {set idx 0} {$idx < [llength $unsorted]} {incr idx} {
            set elem [lindex $unsorted $idx]
            lassign [lindex $elem end] a b
    
            set head [lindex $sorted 0 end]
            set tail [lindex $sorted end end]
    
            if {$a in $head || $b in $head} {
                set sorted [linsert $sorted 0 $elem]
                set changed true
            } elseif {$a in $tail || $b in $tail} {
                lappend sorted $elem
                set changed true
            }
    
            if {$changed} {
                set unsorted [lreplace $unsorted $idx $idx]
                break
            }
        }
    
        # avoid infinite loop if the unsorted list is not empty, but
        # contains nothing to add to the sorted list
        if {! $changed} break
    }
    
    foreach elem $sorted {dict set y {*}$elem}
    
    puts "Unsorted: $x"
    puts "Sorted:   $y"
    
    Unsorted: 12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301}
    Sorted:   55 {44 301} 27 {301 302} 8 {89 302} 29 {89 12} 12 {12 489} 26 {489 329}
    

    【讨论】:

    • 你的方向和我一样,但你更快!似乎工作。一个问题:我现在已经在 TCL 代码中看到过 {wildcard} 之类的东西几次,但我不明白它是什么意思。如果你想要合理的结果,{wildcard} 也很难用谷歌搜索......它在手册中的某个地方吗?
    • 这是 Tcl 语法中的第 5 条规则:tcl.tk/man/tcl8.5/TclCmd/Tcl.htm -- 通常当您说 cmd $foo 时,该命令只接收 1 个参数,即使它是一个列表 -- 当您说 @ 987654325@ 参数被扩展为它的元素,并且该命令接收 $foo 中有多少元素。
    • 此示例代码失败: set p [ dict create 12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301} ] 找到原因我会回来的...
    • 在这种情况下,您有 3 个独立的“链”:29 {89 12} 12 {12 489} 26 {489 329}55 {44 301} 27 {301 302}8 {89 302}——在这种情况下您应该怎么做?诚然,我的代码没有找到所有的链,并且任意从第一个元素开始可能甚至找不到最长的链(尽管在这种情况下碰巧这样做了)。您有什么要求?
    • 这不是某种图构造问题吗?还是一个专业?对于这类事情必须有一些通用算法,但我太累了,记不住细节。
    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2011-02-22
    • 2017-10-13
    相关资源
    最近更新 更多