0

我怎样才能输出这样的结果:

user    I   R   H
=================
atl001  2   1   0
cms017  1   2   1
lhc003  0   1   2

从这样的列表中:

atl001 I
atl001 I
cms017 H
atl001 R
lhc003 H
cms017 R
cms017 I
lhc003 H
lhc003 R
cms017 R

即我想计算I,HR每个用户的数量。只是在这种特殊情况下我不能使用的注释groupbyitertools在此先感谢您的帮助。干杯!!

4

5 回答 5

6
data='''atl001 I
atl001 I
cms017 H
atl001 R
lhc003 H
cms017 R
cms017 I
lhc003 H
lhc003 R
cms017 R'''

stats={}
for i in data.split('\n'):
    user, irh = i.split()
    u = stats.setdefault(user, {})
    u[irh] = u.setdefault(irh, 0) + 1

print 'user  I  R  H'
for user in sorted(stats):
    stat = stats[user]
    print user, stat.get('I', 0), stat.get('R', 0), stat.get('H', 0) 
于 2011-04-17T09:14:40.473 回答
2
data = 112*'cms017 R\n'

data = data + '''atl001 I
cms017 R
atl001 I
cms017 H
atl001 R
lhcabc003 H
cms017 R
lhcabc003 H
lhcabc003 R
cms017 R
cms017 R
cms017 R'''
print data,'\n'

stats = {}
d = {'I':0,'R':1,'H':2}
L = 0
for line in data.splitlines():
    user,irh = line.split()
    stats.setdefault(user,[0,0,0])
    stats[user][d[irh]] += 1
    L = max(L, len(user))

LL = len(str(max(max(stats[user])
                 for user in stats )))

cale = ' %%%ds %%%ds %%%ds' % (LL,LL,LL)
ch = 'user'.ljust(L) + cale % ('I','R','H')

print '%s\n%s' % (ch, len(ch)*'=')
print '\n'.join(user.ljust(L) + cale % tuple(stats[user])
                for user in sorted(stats.keys()))

结果

user        I   R   H
=====================
atl001      2   1   0
cms017      0 117   1
lhcabc003   0   1   2

.

还:

data = 14*'cms017 R\n'

data = data + '''atl001 I
cms017 R
atl001 I
cms017 H
atl001 R
lhcabc003 H
cms017 R
lhcabc003 H
lhcabc003 R
cms017 R
cms017 R
cms017 R'''
print data,'\n'

Y = {}
L = 0
for line in data.splitlines():
    user,irh = line.split()
    L = max(L, len(user))
    if (user,irh) not in Y:
        Y.update({(user,'I'):0,(user,'R'):0,(user,'H'):0})
    Y[(user,irh)] += 1

LL = len(str(max(x for x in Y.itervalues())))

cale = '%%-%ds %%%ds %%%ds %%%ds' % (L,LL,LL,LL)
ch = cale % ('user','I','R','H')

print '%s\n%s' % (ch, len(ch)*'=')
li = sorted(Y.keys())
print '\n'.join(cale % (a[0],Y[b],Y[c],Y[a])
                for a,b,c in (li[x:x+3] for x in xrange(0,len(li),3)))

结果

user       I  R  H
==================
atl001     2  1  0
cms017     0 19  1
lhcabc003  0  1  2

.

PS:

用户名全部用 L 个字符对齐

在我的代码中,为避免塞巴斯蒂安代码中的复杂性,在我的代码中,I、R、H 以相同数量的 LL 字符对齐,这是此列中所有结果的最大值

于 2011-04-17T13:26:20.993 回答
1

好吧,groupby无论如何使用这个问题是没有意义的。对于初学者,您的数据未排序(groupby不会为您排序组),并且行非常简单。

在处理每一行时保持计数。我假设你不知道你会得到什么标志:

from sets import Set as set # python2.3 compatibility
counts = {} # counts stored in user -> dict(flag=counter) nested dicts
flags = set()
for line in inputfile:
    user, flag = line.strip().split()
    usercounts = counts.setdefault(user, {})
    usercounts[flag] = usercounts.setdefault(flag, 0) + 1
    flags.add(flag)

之后打印信息是迭代计数结构的问题。我假设用户名总是 6 个字符长:

flags = list(flags)
flags.sort()
users = counts.keys()
users.sort()
print "user  %s" % ('  '.join(flags))
print "=" * (6 + 3 * len(flags))
for user in users:
    line = [user]
    for flag in flags:
        line.append(counts[user].get(flag, 0))
    print '  '.join(line)

上面的所有代码都未经测试,但应该大致可以工作。

于 2011-04-17T08:46:23.383 回答
1

这是一个使用嵌套字典来计算作业状态并在打印前计算最大字段宽度的变体:

#!/usr/bin/env python
import fileinput
from sets import Set as set # python2.3

# parse job statuses
counter = {}
for line in fileinput.input():
    user, jobstatus = line.split()
    d = counter.setdefault(user, {})
    d[jobstatus] = d.setdefault(jobstatus, 0) + 1

# print job statuses
# . find field widths
status_names = set([name for st in counter.itervalues() for name in st])
maxstatuslens = [max([len(str(i)) for st in counter.itervalues()
                      for n, i in st.iteritems()
                      if name == n])
                 for name in status_names]
maxuserlen = max(map(len, counter))
row_format = (("%%-%ds " % maxuserlen) +
              " ".join(["%%%ds" % n for n in maxstatuslens]))
# . print header
header = row_format % (("user",) + tuple(status_names))
print header
print '='*len(header)
# . print rows
for user, statuses in counter.iteritems():
    print row_format % (
        (user,) + tuple([statuses.get(name, 0) for name in status_names]))

例子

$ python print-statuses.py <input.txt
user   I H R
============
lhc003 0 2 1
cms017 1 1 2
atl001 2 0 1

这是一个使用带有元组(user, status_name)作为键的平面字典的变体:

#!/usr/bin/env python
import fileinput
from sets import Set as set # python 2.3

# parse job statuses
counter = {}
maxstatuslens = {}
maxuserlen = 0
for line in fileinput.input():
    key = user, status_name = tuple(line.split())
    i = counter[key] = counter.setdefault(key, 0) + 1
    maxstatuslens[status_name] = max(maxstatuslens.setdefault(status_name, 0),
                                     len(str(i)))
    maxuserlen = max(maxuserlen, len(user))

# print job statuses
row_format = (("%%-%ds " % maxuserlen) +
              " ".join(["%%%ds" % n for n in maxstatuslens.itervalues()]))
# . print header
header = row_format % (("user",) + tuple(maxstatuslens))
print header
print '='*len(header)
# . print rows
for user in set([k[0] for k in counter]):
    print row_format % ((user,) +
        tuple([counter.get((user, status), 0) for status in maxstatuslens]))

用法和输出是一样的。

于 2011-04-17T15:13:59.637 回答
0

作为提示:

使用嵌套字典结构来计算出现次数:

用户 -> 字符 -> 用户出现的字符

编写解析器代码并增加计数器并打印结果取决于您……一个很好的练习。

于 2011-04-17T08:30:32.680 回答