List 使用TCL从列表中查找给定值的索引号

List 使用TCL从列表中查找给定值的索引号,list,indexing,tcl,List,Indexing,Tcl,需要从列表中找到给定值的索引号。我有一个列表中的值,但我需要找到该值的索引号 set i 0.0001646481396164745 set X [list 1.215647671415354e-7 1.1284486163276597e-6 4.538622670224868e-5 4.4706815970130265e-5 8.492852430208586e-6 6.077577836549608e-6 3.1041158763400745e-6 0.0001504588144598528

需要从列表中找到给定值的索引号。我有一个列表中的值,但我需要找到该值的索引号

set i 0.0001646481396164745
set X [list 1.215647671415354e-7 1.1284486163276597e-6 4.538622670224868e-5 4.4706815970130265e-5 8.492852430208586e-6 6.077577836549608e-6 3.1041158763400745e-6 0.00015045881445985287 4.1016753016265284e-7 1.165599314845167e-6 1.8736355968940188e-6 2.9444883693940938e-5 2.5420340534765273e-5 2.0819682049477706e-6 9.529731869406532e-6 8.549810104341304e-7 1.558014082547743e-5 8.079621693468653e-6 4.868444739258848e-5 0.0001646481396164745]

必须使用TCL从列表X中找到i的索引值。

可以通过以下方法轻松解决:


如果要在只知道近似值的列表中查找浮点值,则不能使用lsearch。相反,你必须自己做:

proc findApprox {theList theValue {epsilon 1e-9}} {
    set idx 0
    foreach x $theList {
        # Found if the difference between the list item and the target is less than epsilon
        if {abs($theValue - $x) < $epsilon} {
            return $idx
        }
        incr idx
    }
    return -1
    # Or [error "not found"] if you prefer
}

set x [findApprox $X $i]

注意epsilon可选参数。这是因为你们们离得有多近取决于你们们对输入数据领域的了解;对于一个基本算法来说,这不是一件容易确定的事情。

虽然直接浮点相等可能很棘手,但首先,如果您知道该值确实存在,例如,如果它以前是从生成该列表的同一来源获取的,则这是正确的方法。但是,您确实需要小心处理浮点值和相等性,因为在Tcl的情况下,浮点数的最低有效位的详细行为严格来说是双精度浮点数。Tcl比一般语言要好一点,因为它有精确的最小浮动→字符串转换,但你仍然会感到惊讶。我也会在这里使用-实物期权,但这是我希望你能从我之前的评论中得到的。干得好。
proc findApprox {theList theValue {epsilon 1e-9}} {
    set idx 0
    foreach x $theList {
        # Found if the difference between the list item and the target is less than epsilon
        if {abs($theValue - $x) < $epsilon} {
            return $idx
        }
        incr idx
    }
    return -1
    # Or [error "not found"] if you prefer
}

set x [findApprox $X $i]