比较两个列表并返回差值 [英] Comparing two lists and returning the difference

查看:64
本文介绍了比较两个列表并返回差值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个列表列表,我将它们匹配并打印任何差异.这两个列表是FPGA站内的电缆连接.我需要确保:

  1. $ list1 上的所有连接都位于 $ list2 上,如果没有,则应将错误保存在另一个列表上

  2. $ list2 上的所有连接都存在于 $ list1 上,因此我没有任何错误"的连接.

  3. 两个列表中都不存在的任何连接都应保存到另一个变量中.

列表采用以下格式:

  {{A.B2} {B.B3}} 

和等价的$ list2可能是:

  {{B.B3} {A.B2}} 

^即使连接已交换,它仍然有效!我将这两个都保存在循环内的不同变量上:

  if {$ physical =="$ project"&&$ physical2 =="$ project2"||$ physical =="$ project2"&&$ physical2 =="$ project"} 然后 {lappend经过验证的"$ project($ project2)VERIFIED \ n"#incr cablecounter设置h 0} elseif {$ physical =="$ project"&&$ physical2!=" $ project2||$ physical!="$ project"&&$ physical2 =="project2"||$ physical =="$ project2"&&$ physical2!=项目"||$ physical!=" $ project2&&$ physical2 ==项目"} 然后 {附加未验证的"$ project到$ project2未连接.请检查$ physical和$ physical2 \ n"} 别的 {设置g [expr $ g-1]增量#puts"\ n [llength配置的连接数]"如果 {$ h>[llength $ configuredConnections]&&$ project!="$ physical"&&$ project2!=" $ physical2||$ h>[llength $ configuredConnections]&&$project != "physical2" &&$ project2!=" $ physical} {将未经验证的附加到"$ project到$ project2的错误连接.请删除.\ n"设置h 0;增量}} 

这给了我所有错误的连接信息,但不是告诉我 $ list1 上的元素在 $ list2 上不存在,而是将其存储到 $ nonverified ,并且列出的是错误连接",而不是列出为未连接".

我是TCL idk的新手!

$ project $ project2 $ list1 $ physical $ physical2 是 $ list2 中的元素.

我正在使用Tcl 8.4

解决方案

ldiff 命令可以为您提供帮助(我将Tcl 8.6实现替换为Tcl 8.4可行的(前提是您使用了 lmap 替换在下面)一个):

  proc ldiff {a b} {lmap elem $ a {expr {[lsearch -exact $ b $ elem]>-1?[继续]:$ elem}}} 

调用

ldiff $list1 $list2 

为您提供 list1 中所有没有出现在 list2 中的元素,反之亦然.

两个列表中都不存在的项目可能应该位于名为 list0 的列表中,您可以通过调用找到它们

  ldiff [ldiff $ list0 $ list1] $ list2 

针对Tcl 8.4用户的 lmap 的快速替代品:

  proc lmap {varname listval body} {upvar 1 $ varname var设置温度[列表]foreach var $ listval {lappend temp [上一级$ body]}设定温度} 

它不允许多个varname-listval对,但是 ldiff 则不需要.

这应该可以代替Tcl 8.4上完整的 lmap 命令,除非使用8.6时仍然没有出现以下问题:

  proc lmap args {设置正文[lindex $ args end]设置参数[lrange $ args 0 end-1]设置n 0设置对[列表]foreach {varname listval} $ args {upvar 1 $ varname var $ n附加对var $ n $ listval增量}设置温度[列表]评估foreach $ pairs [列表{lappend temp [上一级$ body]}]设定温度} 

不过,在这种情况下,我仍然建议您提出第一个替换建议:可以减少出错的地方.

I've got two lists of lists, I match them and print any differences. The two lists are cable connections within a FPGA station. I need to ensure:

  1. All the connections on the $list1 exist on $list2, if not, it should save the error on another list

  2. All the connections on $list2 exist on $list1, so I don't get any 'wrong' connections.

  3. Any connections that don't exist on either list should be saved onto another variable.

The lists are in this format:

{{A.B2} {B.B3}} 

and the the $list2 equivalent could be:

{{B.B3} {A.B2}}

^ Even though the connections are swapped around, it is still valid! I save both of these on different variables inside a loop to do this:

if {
    $physical == "$project" && $physical2 == "$project2"
    || $physical == "$project2" && $physical2 == "$project"
} then {
    lappend verified "$project ($project2) VERIFIED\n"
    #incr cablecounter
    set h 0
} elseif {
    $physical == "$project" && $physical2 != "$project2"
    || $physical != "$project" && $physical2 == "project2"
    || $physical == "$project2" && $physical2 != "project"
    || $physical != "$project2" && $physical2 == "project"
} then {
    lappend nonverified "$project to $project2 NOT connected. Please check $physical and $physical2\n"
} else {
    set g [expr $g - 1]
    incr h
    #puts "\n [llength configuredConnections]"      
    if {
        $h > [llength $configuredConnections] && $project != "$physical" && $project2 != "$physical2"
        || $h > [llength $configuredConnections] && $project != "physical2" && $project2 != "$physical"
    } {
        lappend nonverified "$project to $project2 wrong connection found. Please remove.\n"
        set h 0; incr g
    }   
}

This gives me all the wrong connections etc, BUT instead of telling me that an element on $list1 doesn't exist on $list2, it stores it onto $nonverified, and lists is as a 'wrong connection' rather than listing it as 'NOT' connected.

I am new to TCL idk what to do!

EDIT: $project and $project2 are the two elements in $list1, and $physical $physical2 are elements in $list2.

I'm using Tcl 8.4

解决方案

The ldiff command can help you (EDIT: I replaced the Tcl 8.6 implementation with a Tcl 8.4-workable (provided you use the lmap replacement below) one):

proc ldiff {a b} {
    lmap elem $a {
        expr {[lsearch -exact $b $elem] > -1 ? [continue] : $elem}
    }
}

The invocation

ldiff $list1 $list2

gives you all elements in list1 that don't occur in list2, and vice versa.

Items that don't exist on either of the lists should presumably be in a list named, say, list0, and you can find them with the invocation

ldiff [ldiff $list0 $list1] $list2

A quick-and-dirty replacement for lmap for Tcl 8.4 users:

proc lmap {varname listval body} {
    upvar 1 $varname var
    set temp [list]
    foreach var $listval {
        lappend temp [uplevel 1 $body]
    }
    set temp
}

It doesn't allow multiple varname-listval pairs, but you don't need that for ldiff.

This ought to provide a working replacement for the full lmap command on Tcl 8.4, unless there are still issues that don't show up when using 8.6:

proc lmap args {
    set body [lindex $args end]
    set args [lrange $args 0 end-1]
    set n 0
    set pairs [list]
    foreach {varname listval} $args {
        upvar 1 $varname var$n
        lappend pairs var$n $listval
        incr n
    }
    set temp [list]
    eval foreach $pairs [list {
        lappend temp [uplevel 1 $body]
    }]
    set temp
}

I still recommend the first replacement suggestion in this case, though: there's less that can go wrong with it.

这篇关于比较两个列表并返回差值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆