【问题标题】:Issue with Python ScriptPython脚本问题
【发布时间】:2016-03-24 14:01:04
【问题描述】:

我的代码有问题,我得到以下输出:

回溯(最近一次通话最后一次):
文件“1stHour.py”,第 48 行,在
ws1.cell(column=1, row=i, value="%s" % blue_student_list[i])
IndexError: 列表索引超出范围`

# coding=utf:8
from pythonzenity import Message
from openpyxl.styles import PatternFill
from openpyxl import Workbook
import bluetooth
import time



def student_check(index):
    result = bluetooth.lookup_name(blue_address_list[index], timeout=3)
    if (result is not None):
        return True
    else:
        return False

blue_student_list = ['Name', 'Name2']
blue_address_list = ['Address', 'Address2']


redFill = PatternFill(start_color='FF0000', end_color='FF0000', fill_type='solid')
greenFill = PatternFill(start_color='00FF00', end_color='00FF00', fill_type='solid')


for i in range(0, len(blue_address_list)):

    i = i + 1

    ws1.cell(column=1, row=i, value="%s" % blue_student_list[i])
    if (student_check(i)):
       ws1.cell(column=2, row=i, value="%s" % "Present").fill = greenFill
    else:
       ws1.cell(column=2, row=i, value="%s" % "Absent").fill = redFill


Message(title="Attendance Checker",text="You can now open the Excel Document on your Desktop", timeout=3000)

我有这个工作,但忘记保存它,所以我没有正确的方法,我以前在这里有它。我能做些什么来防止这个错误?我觉得我忘记了什么或在我的代码上写了 i = i + 1 部分。

【问题讨论】:

  • 你不应该做 i = i + 1 因为 i 已经被 for 循环递增并且你的 blue_student_list 没有 len = 3
  • 我将其更改为长度为 3,但它仍然无法正常工作...@SumitKumar
  • 你为什么要在那里增加 i 的值。它在那里做任何具体的事情吗?

标签: python bluetooth openpyxl pybluez


【解决方案1】:

当你这样做时:

for i in range(0, len(blue_address_list)):

没有必要也这样做:

i = i + 1

这样做会导致您看到的错误类型。

您似乎正在这样做,因为您使用的库使用基于 1 的索引,而不是 Python 列表中基于 0 的索引。但是当你这样做时,你仍然使用(1 太高)i 来索引列表:

blue_student_list[i]

因此,不要将i 第二次递增,而是将高 1 的值传递给需要它的事物:

ws1.cell(column=1, row=i+1, value="%s" % blue_student_list[i])

在对ws1.cell 的其他调用中也是如此。

这对于一个 Python 库来说是不寻常的,至少可以说,所以它可能需要在你第一次使用 row=i+1 之前发表这样的评论:

# Need row=i+1 because openPyXML uses 1-based indexing

【讨论】:

  • 与上述用户的输出相同。 OpenPyXL 说“ValueError:行或列值必须至少为 1”。
  • @dylan 查看我的更新答案。似乎您正在尝试解决该库中的一个奇怪问题,但您也需要小心为列表编制正确值的索引。
  • 原来我完全忘记了 wb.save 它。这很有效,而且比原来的更有效。谢谢!
  • openpyxl 使用基于 1 的索引的原因是为了减少切换坐标系时的混乱。然而,正如我自己的回答所证明的那样,几乎不需要使用手动计数器。
【解决方案2】:

行和列在 openpyxl 中是 1 索引的,所以 ws['A1'] 对应于 ws.cell(column=1, row=1)

IndexError 几乎肯定来自blue_student_list[i] 查找。最好使用额外的行来获取值并避免使用“%s”格式,因为这里完全没有必要。

for idx, value in enumerate(blue_student_list, start=1):
    ws1.cell(column=1, row=idx, value=value)

【讨论】:

  • 所以删除for i in range(0, len(blue_address_list)): i = i + 1 部分并用你拥有的替换它?或者删除 i = i + 1 部分并将您的代码添加到 for i in range 部分的末尾?
  • 是的。总的来说,您似乎在与 Python 作斗争。
  • +1;如果可以的话+10。我的回答直接解决了眼前的问题,但是使用更多像enumerate 这样的 Pythonic 习语可以使代码总体上更好,这可能值得我接受。一个(边际)改进可能是将start 作为关键字参数传递给enumerate,而不是简单的数字。 @dylan 要学习这样的 Python 习语,您可能想观看 Raymond Hettinger 的 Transforming Code 视频;还可以考虑在 codereview.SE 上发布,一旦它起作用,你可以做一些不适合 cmets 的小事情。
猜你喜欢
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2014-02-15
相关资源
最近更新 更多