计算列表中唯一元素的数量
Count number of unique element in a list
假设我有一个列表,a b c b b d e e f …
,我不知道里面有多少种不同的元素。
如何计算每个唯一元素的数量并打印出来?
输出看起来像:
a: 32
b: 12
c: 6
…
你得数一数。这对于计数器数组或字典来说并不难。我将使用字典,因为它们将按首次出现的顺序打印。 (对于数组,您会得到一个“随机”顺序,或者您必须对它们进行排序。)
set counters {}
foreach item $list {
dict incr counters $item
}
dict for {item count} $counters {
puts "${item}: $count"
}
如果您有 8.4 或更旧版本的 TCL,请尝试此操作,
set lst "a a a a b b b c c c d d a a a f f f f f s s s s"
set unique [lsort -unique $lst]
foreach f $unique {
set cnt 0
foreach item $lst {
if {$item == $f} {
incr cnt
}
}
puts "$f :: $cnt"
}
给出类似的输出,
% tclsh main.tcl
a :: 7
b :: 3
c :: 3
d :: 2
f :: 5
s :: 4
dict
或 array
解决方案是最好的解决方案,应该首选。另一种适用于已排序标记列表的方法是匹配非空白标记的连续区域。
% regexp -all -inline {(\S+)(?:\s+)*} {a a b b b c d d}
{a a} a {b b b} b c c {d d} d
结果是一个均匀大小的列表,其中包含交替匹配的令牌区域和该区域中匹配的令牌。这可用于打印 list
.
列表中标记的频率报告
foreach {a b} [regexp -all -inline {(\S+)(?:\s+)*} [lsort $list]] {
puts "$b: [llength $a]"
}
注意标记不能包含空格的限制。这可以克服,但使用数组/字典解决方案更简单,它只需要标记是有效的列表元素。
文档:foreach, llength, lsort, puts, Syntax of Tcl regular expressions, regexp
使用 lsearch 和 llength 可以轻松完成。
假设您的列表是 {a c a c s a a c a} 那么,
set tempList {a c a c s a a c a}
puts "c : [llength [lsearch -all $tempList c]]"
puts "a : [llength [lsearch -all $tempList a]]"
puts "d : [llength [lsearch -all $tempList d]]"
输出:
c : 3
一:5
d : 0
解释:lsearch -all,将return所有匹配元素的索引
并且这个索引列表被return编辑为llength,它将计算列表的长度。
假设我有一个列表,a b c b b d e e f …
,我不知道里面有多少种不同的元素。
如何计算每个唯一元素的数量并打印出来? 输出看起来像:
a: 32 b: 12 c: 6 …
你得数一数。这对于计数器数组或字典来说并不难。我将使用字典,因为它们将按首次出现的顺序打印。 (对于数组,您会得到一个“随机”顺序,或者您必须对它们进行排序。)
set counters {}
foreach item $list {
dict incr counters $item
}
dict for {item count} $counters {
puts "${item}: $count"
}
如果您有 8.4 或更旧版本的 TCL,请尝试此操作,
set lst "a a a a b b b c c c d d a a a f f f f f s s s s"
set unique [lsort -unique $lst]
foreach f $unique {
set cnt 0
foreach item $lst {
if {$item == $f} {
incr cnt
}
}
puts "$f :: $cnt"
}
给出类似的输出,
% tclsh main.tcl
a :: 7
b :: 3
c :: 3
d :: 2
f :: 5
s :: 4
dict
或 array
解决方案是最好的解决方案,应该首选。另一种适用于已排序标记列表的方法是匹配非空白标记的连续区域。
% regexp -all -inline {(\S+)(?:\s+)*} {a a b b b c d d}
{a a} a {b b b} b c c {d d} d
结果是一个均匀大小的列表,其中包含交替匹配的令牌区域和该区域中匹配的令牌。这可用于打印 list
.
foreach {a b} [regexp -all -inline {(\S+)(?:\s+)*} [lsort $list]] {
puts "$b: [llength $a]"
}
注意标记不能包含空格的限制。这可以克服,但使用数组/字典解决方案更简单,它只需要标记是有效的列表元素。
文档:foreach, llength, lsort, puts, Syntax of Tcl regular expressions, regexp
使用 lsearch 和 llength 可以轻松完成。
假设您的列表是 {a c a c s a a c a} 那么,
set tempList {a c a c s a a c a}
puts "c : [llength [lsearch -all $tempList c]]"
puts "a : [llength [lsearch -all $tempList a]]"
puts "d : [llength [lsearch -all $tempList d]]"
输出:
c : 3
一:5
d : 0
解释:lsearch -all,将return所有匹配元素的索引 并且这个索引列表被return编辑为llength,它将计算列表的长度。