Openpyxl从字典中的两个不同Excel行添加键、值对

2024-10-03 00:19:09 发布

您现在位置:Python中文网/ 问答频道 /正文

在这里,我试图将特定行中的单元格值保存为键,将另一行中的单元格值保存为值,全部保存在字典中

使用下面的代码,我成功地将第一行(绿色标记)保存为字典中的键

但我正在努力解决的是,将第二行(黄色标记)保存为字典中的值

dictData = {}

#get row 2 
for row1 in ws1.iter_rows(min_row=2, max_row=2, min_col=3, max_col=ws1.max_column):
    for cell1 in row1:
        #get row 5
        for row2 in ws1.iter_rows(min_row=5, max_row=row_data, min_col=5, max_col=ws1.max_column):
            for cell2 in row2:
                    dictData[cell1.value] = cell2.value

Table

在运行上述代码时,它只为字典中的每个值存储行中的最后一个数据(“20”-来自中国的数据)

{'Total': 20, 'USA': 20, 'Canada': 20, 'UK': 20, 'France': 20, 'Germany': 20, 'India': 20, 'Japan': 20, 'Singapore': 20, 'China': 20}

有人对如何解决这个问题有任何想法/反馈吗?当然,我在“For循环”中遗漏了一些东西

谢谢!:)


Tags: 代码in标记forget字典colmin
3条回答

尽量不要嵌套迭代。单独阅读第2行

然后从5迭代到某物

如果您需要某些内容的标题,请将其存储在不同的目录中,例如,以列名作为键。然后稍后访问它

您可以从第一行创建以下词典:

headers = {1:'Total', 2:'USA'}

稍后,当您遍历其余的行和列时,您可以访问它以获得 名称您知道列索引。也许你需要修正偏移量之类的

some_other_dictionary = {headers[column_index]: 'some_value'}

另一种可能是使用像pandas.read_excel这样的东西,它应该为您完成艰苦的工作

只是看看你的共享数据;因为您只对两行(第2行和第5行)感兴趣,所以可以分别读取它们,压缩数据,并记录压缩后的数据。相关数据从第3列开始,因此我也包括:

from openpyxl import load_workbook
filename = 'Project_yxz.xlsx'

wb = load_workbook(filename)
ws = wb.active

#read in the data
row2 = ws.iter_rows(min_row=2, max_row=2, min_col=3, values_only=True)
row5 = ws.iter_rows(min_row=5, max_row=5, min_col=3, values_only=True)

#zip and dict
res = dict(zip(*row2,*row5))

res

{'Total': 720,
 'USA': 72,
 'Canada': 34,
 'UK': 54,
 'France': 46,
 'Germany': 38,
 'India': 120,
 'Japan': 101,
 'Singapore': 47,
 'China': 20}

让我知道这是否是你的想法。进一步阅读openpyxl文档here

这不需要嵌套循环。对于每个外部值(dict键),您只需要一个内部值(dict值)。因此,内部循环的大小应为1,这根本不是循环

但是,您当然必须将内部值与外部值对齐。在大多数经典编程语言中,这可以通过在用于处理这两个项的索引上循环来实现,即

# Naive way
dictData = {}
for i in range(2, len(ws1[3])):
    dictData[ws1[3][i].value] = ws1[5][i].value

然而,这并不是很像Python,因为Python允许直接在值上循环。但仅在外部值上循环,仍然需要内部值的索引。可以使用循环中的enumerate来获取值及其索引:

# Enumerate inner value (not very nice)
dictData = {}
for i, key in enumerate(ws1[3][2:], 2):
    dictData[key.value] = ws1[5][i].value 

不过,由于我们仍然需要一个索引,因此这并没有带来多少好处。我们确实希望能够直接从循环中获取dict键和dict值。瞧,Python为我们准备了一个解决方案,即使用zip,它允许我们在一个for循环中对齐两个系列:

# Using zip, nicer and more pythonic
dictData = {}
for key, value in zip(ws1[3][2:], ws1[5][2:]):
    dictData[key.value] = value.value 

现在我们正在取得进展。这更像它,但我们可以更进一步,使用所谓的dict理解,它允许我们一次性创建和分配dict:

# dict comprehension
dictData = {key.value: value.value for key, value in zip(ws1[3][2:], ws1[5][2:])}

我想说,虽然我更喜欢听写理解,因为我觉得它很容易阅读,但你的理解可能会有所不同

另外,作为最后一点,为了让代码感觉更像python,将camelCaseddictData替换为更符合PEP8的形式dict_data。但是,只有在项目中的所有变量都使用这种样式时,这才是正确的。更重要的是保持一致

相关问题 更多 >