2013-11-02 171 views
0

我正在写一个Python 3脚本,并制表林业木材计数可变长度命令的元组。处理与尝试......除了

工人将电台种类,平均直径,并且在每棵树的日志高度它们标记为电脑操作员。然后,计算机操作员将进入一个命令,例如这样的:

OAK 14 2 

这意味着该方案应增加直径14英寸和两个日志高度橡树计数。

但是,工作人员有时也会同时呼叫同一类型的树中的一个以上。所以程序也必须能够处理这个命令:

OAK 16 1 2 

这将意味着我们正在增加两个计数。

我有解析器设置方式是这样的:

key=cmdtup[0]+"_"+cmdtup[1]+"_"+cmdtup[2] 
     try: 
      trees[key]=int(trees[key])+int(cmdtup[3]) 
     except KeyError: 
      trees[key]=int(cmdtup[3]) 
     except IndexError: 
      trees[key]=int(trees[key])+1 

如果程序命令来存储它之前没有存储一棵树,一个KeyError异常会熄灭,处理程序将设置字典输入,而不是增加它。如果省略第三个参数,一个IndexError将提高,而处理器将它视为如果第三个参数是发生1

问题,但是,如果我们在一次这两种情况下,该计划还没有听说过橡树,并且运营商没有指定计数。 KeyError会关闭,但会自动生成一个IndexError,并且在异常处理程序中发生异常时,Python不会喜欢它。

我想最简单的方法是简单地删除一个或另一个不同之处,并有其功能可以用另一种方式来完成。不过,我想知道是否有更优雅的Pythonic方法来完成此任务。在那儿?

+0

不要欺负你的程序用户强迫他们在cmd.exe中输入参数,例如。这是残酷的。创建一些前端。 – Artur

+0

它不能通过argv工作。在我发布的位之上有一个输入循环。另外,我是最终用户。 – Schilcote

+0

有什么答案可以接受? – uselpa

回答

0

最后,最好的方法是简单地删除IndexError处理程序,将cmdtup更改为列表并插入以下代码:

if len(cmdtup) >= 3: 
    cmdtup.append(1) 
0

我会做这样的事情:

def parse(cmd, trees): 
    res = cmd.split() # split the string by spaces, yielding a list of strings 
    if len(res) == 3: # if we got 3 parameters, set the fourth to 1 
     res.append(1) 
    for i in range(1,4): # convert parameters 1-3 to integers 
     res[i] = int(res[i]) 
    key = tuple(res[x] for x in range(3)) # convert list to tuple, as lists cannot be dictionary indexes 
    trees[key] = trees.get(key,0) + res[3] # increase the number of entries, creating it if needed 

trees={} 

# test data 
parse("OAK 14 2", trees) 
parse("OAK 16 1 2", trees) 
parse("OAK 14 2", trees) 
parse("OAK 14 2", trees) 

# print result 
for tree in trees: 
    print(tree, "=", trees[tree]) 

产生

('OAK', 16, 1) = 2 
('OAK', 14, 2) = 3 

一些注意事项:

  • 没有的错误处理,你应该处理的情况下,当值应该是一个数字是不是或输入是错误的任何其他方式
  • 而不是字符串,我用的元组作为字典指数
0

你可以使用collections.Counter,如果该键不在字典中返回0,而不是一个KeyError

Counter Documentation:

Counter对象都有一本字典的接口,除了它们返回一个零计数丢失物品而不是引发一个KeyError

事情是这样的:

from collections import Counter 

counts = Counter() 

def update_counts(counts, cmd): 
    cmd_list = cmd.split() 
    if len(cmd_list) == 3: 
     tree = tuple(cmd_list) 
     n = 1 
    else: 
     *tree, n = tuple(cmd_list) 
    counts[tree] += n 

相同的注释适用于uselpa的回答。 Counter的另一个好处是,如果你想,例如,看每周计数,你只需要做一些事情,如sum(daily_counts)

Counter作品甚至更好,如果你从命令的列表开始:

from collections import Counter 
from itertools import repeat 

raw_commands = get_commands() # perhaps read a file 
command_lists = [c.split() for c in raw_commands] 

counts = Counter(parse(command_lists)) 

def parse(commands): 
    for c in commands: 
     if len(c) == 3: 
      yield tuple(c) 
     elif len(c) == 4 
      yield from repeat(tuple(c[0:2]), times=c[3]) 

从那里,你可以使用update_counts功能上面添加新的树木,你就可以开始在另一个文本收集命令文件,然后在第二天,下一周等生成第二个Counter对象。