简体   繁体   中英

How to “zip” lists in tcl

I have three lists :

set l1 {1 2 3}
set l2 {'one' 'two' 'three'}
set l3 {'uno' 'dos' 'tres'}

and I would like to build this list :

{{1 'one' 'uno'} {2 'two' 'dos'} {3 'three' 'tres'}}

In python , I would use something like the built-in function zip . What should I do in tcl ? I have looked in the documentation of 'concat' , but haven't find a priori relevant commands.

If you're not yet on Tcl 8.6 (where you can use lmap ) you need this:

set zipped {}
foreach a $l1 b $l2 c $l3 {
    lappend zipped [list $a $b $c]
}

That's effectively what lmap does for you, but it was a new feature in 8.6.

lmap a $l1 b $l2 c $l3 {list $a $b $c}

List map, lmap , is a mapping command that takes elements from one or more lists and executes a script. It creates a new list where each element is the result of one execution of the script.

Documentation: list , lmap

This command was added in Tcl 8.6, but can easily be added to earlier versions.

Getting lmap for Tcl 8.5 and earlier

Here's a version that takes an arbitrary number of list names:

set l1 {a b c}
set l2 {d e f}
set l3 {g h i j}

proc zip args {
    foreach l $args {
        upvar 1 $l $l
        lappend vars [incr n]
        lappend foreach_args $n [set $l]
    }
    foreach {*}$foreach_args {
        set elem [list]
        foreach v $vars {
            lappend elem [set $v]
        }
        lappend result $elem
    }
    return $result
}

zip l1 l2 l3
{a d g} {b e h} {c f i} {{} {} j}

Requires Tcl 8.5 for the {*} argument expansion.

An 8.6 version

proc zip args {
    foreach l $args {
        upvar 1 $l $l
        lappend vars [incr n]
        lappend lmap_args $n [set $l]
    }
    lmap {*}$lmap_args {lmap v $vars {set $v}}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM