2012-04-11 66 views
0

我想在XL中打开工作表。该工作表可以被命名为“地图”,“地图”或“地图”嵌套try语句打开XL表

这是我在做什么

import xlrd 
book = xlrd.open_workbook(xls) // where xls is the name of the spreadsheet 
try: 
    sheet = book.sheet_by_name('map') 
except: 
    try: 
     sheet = book.sheet_by_name('Map') 
    except: 
     try: 
      sheet = book.sheet_by_name('MAP') 
     except: 
      raise 

这看起来很笨重......有没有这样做的更pythonic的方法

回答

1

虽然不完全像一些其他方法为可读,可能是最短的方法是使用:

sheet = book.sheet_by_name(list(set(['map', 'Map', 'MAP']) & set(book.sheet_names())[0]) 

基本上,这使用列表路口的通过另一个提出的概念,以便回答。可能是一个更简单的方法来创建此,以便更易于阅读:

possibleNames = ['map', 'Map', 'MAP'] 
sheetNames = book.sheet_names() 
name = intersect(possibleNames, sheetNames) 
if len(name) < 1: 
    print "Error" 
    # break program appropiately 
sheet = book.sheet_by_name(name[0]) 

def intersect(a, b): 
    return list(set(a) & set(b)) 
+0

也有可能有多个名字可能起作用,例如可能存在Map和MAP。迭代方法可让您决定覆盖哪个名称。使用'[0]'只需按照'set'代码选择的顺序选择它们,不一定是人们想要的。如果你有一长串可能的名字,'set'方法会更快,并且在其他情况下很好记住。 :-) – torek 2012-04-11 01:33:14

+0

@torek:尝试用2或3个这样的名字在excel中创建工作簿...它不会让你。 – 2012-04-11 23:23:58

+0

-1完全在顶部。看到我的答案。 – 2012-04-11 23:40:19

4

只是迭代的可能性,试图打开每一个依次为:

sheet = None 
for thing in ['map','Map','MAP']: 
    try: 
    sheet = book.sheet_by_name(thing) 
    break 
    except: 
    pass 

这种运行后,sheet将被设置为第一thing那可能会被打开。如果没有人可以打开,那么sheet将是None

+0

+1,我即将发布类似的东西,但你打败了我。但是,如果能够明确处理* thing *的任何操作(OP会重新引发最后一个异常)的情况将会很有用 - 循环中的'else'子句对此非常适用。而且,除了'except:'(就像OP中的几个类似的)应该明确提及'sheet_by_name'在名称错误时引发的特殊异常。 – lvc 2012-04-11 00:28:08

2

Excel工作表名称不区分大小写。 Excel不允许您在单个工作簿中创建多个名称(地图,地图,MAP,maP等)的工作表。

candidates = [n for n in book.sheet_names() if n.lower() == 'map'] 
assert len(candidates) in (0, 1) 
if candidates: 
    sheet = book.sheet_by_name(candidates[0]) 
else: 
    whatever() 

也许你想提出一个增强请求,要求Book.sheet_by_name使用不区分大小写的搜索。