for循环内部的字典导致TypeError,在for循环之外工作正常

时间:2017-07-03 16:58:03

标签: python dictionary

好的,基本上我要做的是搜索excel文件中列中的所有值,然后如果它们匹配单独文本文件中的任何数据值,则将它们标记为绿色。

如果我的代码难以阅读,我很抱歉,还是一个初学者。

所以下面会运行正常并打印字典“dictIPExcel”没有问题:

dictIPExcel = {}
##############IMPORTANT CHANGE HERE, FILE NAME########################
#Change file name here to suit your file
wb = openpyxl.load_workbook('file.xlsx')
#Copy sheet name here
sheet = wb.active

#What font color to change to below

greenFill = PatternFill(start_color='0000B200', end_color='0000B200', fill_type='solid')

#This will create a list containing every line in the below txt file
IPlist = open('No Config or Denied devices.txt').read().split('\n')

#Loops through A19-A100, gathering the value in each row into dictIPExcel
for t in range(19,100):
    dictIPExcel["A{0}".format(t)] = sheet['A'+ str(t)].value
print dictIPExcel
sheetz = wb.sheetnames

for a in sheetz:
    sheet = a
    dictIPExcel = {}

    for l in range(19,100):
        for x,y in dictIPExcel.items():
            for z in IPlist:
                if y == z:
                    print "match"
                    sheet[x].fill = greenFill
wb.save('textCopy4.xlsx')

但是,如果我将“dictIPExcel”移动到第二个for循环内,它会抛出'TypeError:字符串必须是整数。'根据我的理解,这意味着将'A50'作为字典中的索引基本上是不行的。我的问题是为什么这在循环之外工作?字典中的数据索引不会在循环外部对内部进行更改,但错误仅在内部进行。内部循环代码:

for a in sheetz:
    sheet = a
    dictIPExcel = {}
    for t in range(19,100):
        dictIPExcel["A{0}".format(t)] = sheet['A'+ str(t)].value
    for l in range(19,100):
        for x,y in dictIPExcel.items():
            for z in IPlist:
                if y == z:
                    print "match"
                    sheet[x].fill = greenFill

以下是输出:

Traceback (most recent call last):
  File "C:..\testing.py", line 49, in <module>
    dictIPExcel["A{0}".format(t)] = sheet['A'+ str(t)].value
TypeError: string indices must be integers

我能做些什么来让它在循环中运行吗?或者也许还有一种更好的方法可以解决我在浏览每张工作表并突出显示匹配数据时要做的事情?

4 个答案:

答案 0 :(得分:3)

我认为这与dictIPExcel无关。该错误表示变量sheetstr,而不是dict,因为您正在对其进行处理。

看看:

#Copy sheet name here
sheet = wb.active

然后你在这里覆盖它:

for a in sheetz:
    sheet = a

我假设str基于sheetz = wb.sheetnames

这是对python的常见误解。 For循环没有自己的变量名称空间,内部变量可以在其范围之外破坏变量。例如:

>>> for i in range(5): pass
... 
>>> print i
4
>>> 

如果你在循环中使用另一个变量(sheet_name?),你应该很好。

祝你好运!

答案 1 :(得分:1)

在第一种情况下(正确的)

sheet = wb.active

所以sheet字典。

在第二个(不正确的)情况下,

sheet = a   # for a in sheetz, where  sheetz = wb.sheetnames

sheet列表(因此需要整数索引)。

答案 2 :(得分:0)

sheetz是工作表名称列表,它们是字符串。您需要使用wb.get_sheet_by_name

获取句柄
for a in sheetz:
    sheet=wb.get_sheet_by_name(a)
    dictIPExcel = {}
    for t in range(19,100):
        dictIPExcel["A{0}".format(t)] = sheet['A' + str(t)].value

答案 3 :(得分:0)

好的,对我来说有用的最终工作设置如下,对于将来可能遇到类似问题的人。我认为上述两个答案都是正确的,但主要问题是我忘记调用.get_sheet_by_name()函数:

for a in sheetz:
    sheet2 = wb.get_sheet_by_name(a)
    dictIPExcel = {}
    for t in range(19,100):
        dictIPExcel["A{0}".format(t)] = sheet2['A'+ str(t)].value
    for l in range(19,100):
        for x,y in dictIPExcel.items():
            for z in IPlist:
                if y == z:
                    print "match"
                    sheet2[x].fill = greenFill
wb.save('Copy.xlsx')

通过此更改,脚本可以正常工作,现在我已经有了一个适当的绿化工作簿。 :)