xlwt 写入 Excel 文件的 Python 问题

-1 投票
2 回答
5310 浏览
提问于 2025-04-16 22:06

我有两个不同的数据列表,一个是单词列表(wordlist),另一个是数字列表(digitlist)。这两个列表的数据是相关的,也就是说,wordlist[1] 和 digitlist[1] 是一对一对应的。下面是这两个数据集的内容:

seglist = ['aaa111', 'bbb222', 'ccc333']
wordlist = ['aaa', 'bbb', 'ccc']
digitlist = ['111', '222', '333']

我想为每一组数据创建一个新的工作表,把单词列表放在第一列,把数字列表放在第二列。现在,下面这段代码在我只包含一组数据时是可以正常工作的:

for i in range(len(seglist)):
p = str(i)
ws = w.add_sheet(p)
for i, cell in enumerate(wordlist[i]):
    ws.write(i,0,cell)

但是当我尝试添加第二组数据时,它就报错了。我觉得问题可能出在 Excel 工作表不能被写入两次。那么这是不是意味着我需要重新打开新创建的 Excel 文件,然后再进行格式化呢?另外,有没有人知道如何在 Excel 表格中同时写入这两组数据的方法?

for i in range(len(seglist)):
p = str(i)
ws = w.add_sheet(p)
for i, cell in enumerate(wordlist[i]):
    ws.write(i,0,cell)
    for i, cell in enumerate(digitlist[i]):
        ws.write(i,1,cell)
Exception: Attempt to overwrite cell: sheetname=u'0' rowx=0 colx=1

还有,每个数据集中的项目数量可能不一样。

2 个回答

1

问题在于,你的第二个循环一直在重复访问同样的单元格。

也就是说,假设你的数据看起来像这样:

wordlist = [['cat','feline','kitty'], ['dog','canine','puppy']]
digitlist = [[3,7,9000],[17,8,4000]]

当你处理 wordlist 时,你会写:

Sheet0
    Row0
    -----
    cat
    feline
    kitty
Sheet1
    Row0
    -----
    dog
    canine
    puppy

当你把对 digitlist 的循环加进来的时候,你就会对每一个 wordlist[i] 中的条目,运行所有的 digitlist[i] 中的条目。

所以你的程序会把 "cat" 写入第0行,第0列,也就是 (0,0),然后把 3、7 和 9000 写入 (0,1)(1,1)(1,2)。接着,程序会把 "feline" 写入 (1,0) ... 然后又试图把 3、7 和 9000 再次写入 (0,1)(1,1)(1,2) 另外,内部的 i 会覆盖外部的 i ... 如果没有覆盖(比如你在内部循环中用 ii),那么你就会尝试把 17、8 和 4000 写入 (0,1)(1,1)(1,2) ... 这可能根本不是你想要的结果。

如果你想把单词列表和数字列表合并,并把它们写在一起,可以试试 zip

for i in range(len(wordlist)):
    merged = zip(wordlist[i], digitlist[i])
    cells = range(len(merged[0])) # Assumes no ragged arrays
    for row in range(len(merged)):
        for col in cells:
            ws.write(row, col, merged[row][col])
1

你提供的两段代码(在你的问题中展示的)都没法正常工作,原因有两个:第一,缩进有问题;第二,你在每一个 for 循环中都用了同一个变量 i

你需要先修正缩进,然后把循环中的变量名换成更有意义的名字,比如 sheet_indexrow_indexcol_index(如果你想少按几个键,也可以用 sheetx、rowx、colx)。

seglist 是什么呢?

“Excel 表格不能重复写入”——其实不是这样的。默认情况下,xlwt 不允许你在同一个 单元格 中写入两次。根据经验,99.99% 的时候,问题出在逻辑不清晰上。需要覆盖单元格内容的人(在你上面的任务中并不需要)可以绕过这个检查。

所以,把这些信息结合起来,下面的代码实现了我理解的内容:“我想为每组数据创建一个新表,并在表的第一列写入单词列表,第二列写入数字列表。”

assert len(wordlist) == len(digitlist)
for sheetx in xrange(len(seglist)):
    ws = w.add_sheet(str(sheeetx))
    assert len(wordlist[sheetx]) == len(digitlist[sheetx])
    for rowx, values in enumerate(zip(wordlist[sheetx], digitlist[sheetx]):
        for colx, value in enumerate(values):
            ws.write(rowx, colx, value)

如果有任何 assert 触发,你需要检查一下你的数据……

更新:根据关于不规则数据的信息进行的回应:

assert len(wordlist) == len(digitlist) == len(seglist))
for sheetx in xrange(len(seglist)):
    ws = w.add_sheet(str(sheeetx))
    for colx, values in enumerate((wordlist[sheetx], digitlist[sheetx])):
        for rowx, value in enumerate(values):
            ws.write(rowx, colx, value)

撰写回答