如何从重复值列表中获取唯一值集

时间:2011-02-12 07:39:55

标签: python perl parsing

我需要解析一个大的日志文件(平面文件),它包含两列值(列A,列B)。

两列中的值都在重复。我需要找到列A中的每个唯一值,我需要找到一组列B值。

这可以使用unix shell命令完成还是需要编写任何perl或python脚本?有什么办法可以做到?

实施例

xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4

输出:

xxxA - 2,1,3
xxxB - 2
xxxC - 3
xxxD - 4

7 个答案:

答案 0 :(得分:5)

Perl'one-liner'意图/扩展,以便所有东西都适合窗口:

$ perl -F -lane '

      $hash{ $F[0] }{ $F[1] }++;
  } END {

      for my $columnA ( keys %hash ) {

          print $columnA, " - ", join( ",", keys %$hash{$columnA} ), "\n";
      }
  '

如果我看到原始海报的一致尝试,将会有解释。

答案 1 :(得分:3)

我会使用Python词典,其中字典键是A列值,字典值是Python内置Set type保留B列值

def parse_the_file():
    lower = str.lower
    split = str.split
    with open('f.txt') as f:
        d = {}
        lines = f.read().split('\n')
        for A,B in [split(l) for l in lines]:
            try:
                d[lower(A)].add(B)
            except KeyError:
                d[lower(A)] = set(B)

        for a in d:
            print "%s - %s" % (a,",".join(list(d[a])))

if __name__ == "__main__":
    parse_the_file()

使用字典的优点是每列A值只有一个字典键。使用集合的优点是您将拥有一组唯一的B列值。

效率说明:

  • 使用try-catch比使用if \ else语句检查初始情况更有效。
  • 在循环外部评估和分配str函数比在循环中简单地使用它们更有效。
  • 根据新A值与整个文件中A值重新出现的比例,您可以考虑在try catch语句之前使用a = lower(A)
  • 我使用了一个函数,因为访问局部变量在Python中比访问全局变量更有效
  • 其中一些效果提示来自here

在输入示例上测试上面的代码会产生:

xxxd - 4
xxxa - 1,3,2
xxxb - 2
xxxc - 3

答案 2 :(得分:1)

您可以使用这个简单的多图:

class MultiMap(object):
    values = {}

    def __getitem__(self, index):
        return self.values[index]
    def __setitem__(self, index, value):
        if not self.values.has_key(index):
            self.values[index] = []
        self.values[index].append(value)
    def __repr__(self):
        return repr(self.values)

查看实际操作:http://codepad.org/xOOrlbnf

答案 3 :(得分:1)

Simple Perl版本:

#!/usr/bin/perl

use strict;
use warnings;

my (%v, @row);

foreach (<DATA>) {
        chomp;
        $_ = lc($_);
        @row = split(/\s+/, $_);
        push( @{ $v{$row[0]} }, $row[1]);
} 

foreach (sort keys %v) {
        print "$_ - ", join( ", ", @{ $v{$_} } ), "\n";
}

__DATA__
xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4

没有关注变量名称。从示例中我看到它们不区分大小写。

答案 4 :(得分:0)


f = """xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4"""


d = {}

for line in f.split("\n"):
    key, val = line.lower().split()
    try:
        d[key].append(val)        
    except KeyError:
        d[key] = [val]


print d

的Python

答案 5 :(得分:0)


while() {

($key, $value) = split / /, $_;

$hash{lc($key)} = 1;

push(@array, "$key$value");

}

foreach $key (sort keys %hash) {

@arr = (grep /$key/i, @array);

chomp(@arr);

$val = join (", ", @arr);

$val =~ s#$key##gi; 

print "$key\t$val\n";

}

答案 6 :(得分:0)

使用Perl oneliner:

perl -lane'$F[0]=~s/.../lc$&/e;exists$s{$F[0]}and$s{$F[0]}.=",$F[1]"or push@v,$F[0]and$s{$F[0]}=$F[1]}{print"$_ $s{$_}"for@v'

如果您的密钥区分大小写(在测试数据中不正确),则可以删除$F[0]=~s/.../lc$&/e;;如果您可以将密钥统一到较低或较高级别,则可以使用$F[0]=lc$F[0];$F[0]=uc$F[0];情况下。

相关问题