Openpyxl - 添加来自字典中两个不同 Excel 行的键值对
Openpyxl - Add key,value pairs from two different Excel rows in a dictionary
我在这里尝试将特定行的单元格值保存为键,将另一行的单元格值保存为值,所有这些都在字典中。
使用下面的代码,我设法将第一行(绿色标记)保存为字典中的键。
但我正在努力的是将第二行(黄色标记)保存为字典中的值。
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
虽然 运行 上面提到的代码,它为字典中的每个值存储了行中的最后一个数据(“20”-来自中国的数据)。
{'Total': 20, 'USA': 20, 'Canada': 20, 'UK': 20, 'France': 20, 'Germany': 20, 'India': 20, 'Japan': 20, 'Singapore': 20, 'China': 20}
有人 idea/feedback 知道如何解决这个问题吗?我肯定在 'for loop'.
中遗漏了一些东西
谢谢! :)
尽量不要嵌套迭代。单独阅读第 2 行。
然后从 5 迭代到某个值。
如果您需要 header 的东西,请将其存储在不同的目录中,例如以列名作为键。以后再访问。
您从第一行开始创建以下字典:
headers = {1:'Total', 2:'USA'}
稍后当您遍历其余的行和列时,您可以访问它以获取
名称。你知道列索引。也许您需要修复偏移量或其他内容。
some_other_dictionary = {headers[column_index]: 'some_value'}
另一种可能性是使用 pandas.read_excel 之类的东西,它应该会为您完成艰苦的工作。
这不会调用嵌套循环。对于每个外部值(字典键),您只需要一个内部值(字典值)。因此,内部循环应该关闭大小 1,这根本就不是循环。
但是,你当然要让你的内在价值观与外在价值观保持一致。在大多数经典编程语言中,这将通过循环遍历用于解决这两个项目的索引来实现,即
# Naive way
dictData = {}
for i in range(2, len(ws1[3])):
dictData[ws1[3][i].value] = ws1[5][i].value
然而,这不是很 pythonic,因为 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
不过,这样做并没有多大好处,因为我们仍然需要一个索引。我们真的希望能够直接从循环中获取字典键和字典值。而且,瞧瞧,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 comprehension
dictData = {key.value: value.value for key, value in zip(ws1[3][2:], ws1[5][2:])}
最后两个都可以,我会说,尽管我更喜欢听写理解,因为我发现它很容易阅读,但你的里程数可能会有所不同。
此外,作为最后一点,为了让代码感觉更像 pythonic,请将驼峰式 dictData
替换为更符合 PEP8 的形式 dict_data
。但这当然只有在项目中的所有变量都使用该样式时才是正确的。保持一致更重要。
刚刚查看了您的共享数据;因为您只对两行(第 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
我在这里尝试将特定行的单元格值保存为键,将另一行的单元格值保存为值,所有这些都在字典中。
使用下面的代码,我设法将第一行(绿色标记)保存为字典中的键。
但我正在努力的是将第二行(黄色标记)保存为字典中的值。
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
虽然 运行 上面提到的代码,它为字典中的每个值存储了行中的最后一个数据(“20”-来自中国的数据)。
{'Total': 20, 'USA': 20, 'Canada': 20, 'UK': 20, 'France': 20, 'Germany': 20, 'India': 20, 'Japan': 20, 'Singapore': 20, 'China': 20}
有人 idea/feedback 知道如何解决这个问题吗?我肯定在 'for loop'.
中遗漏了一些东西谢谢! :)
尽量不要嵌套迭代。单独阅读第 2 行。
然后从 5 迭代到某个值。
如果您需要 header 的东西,请将其存储在不同的目录中,例如以列名作为键。以后再访问。
您从第一行开始创建以下字典:
headers = {1:'Total', 2:'USA'}
稍后当您遍历其余的行和列时,您可以访问它以获取 名称。你知道列索引。也许您需要修复偏移量或其他内容。
some_other_dictionary = {headers[column_index]: 'some_value'}
另一种可能性是使用 pandas.read_excel 之类的东西,它应该会为您完成艰苦的工作。
这不会调用嵌套循环。对于每个外部值(字典键),您只需要一个内部值(字典值)。因此,内部循环应该关闭大小 1,这根本就不是循环。
但是,你当然要让你的内在价值观与外在价值观保持一致。在大多数经典编程语言中,这将通过循环遍历用于解决这两个项目的索引来实现,即
# Naive way
dictData = {}
for i in range(2, len(ws1[3])):
dictData[ws1[3][i].value] = ws1[5][i].value
然而,这不是很 pythonic,因为 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
不过,这样做并没有多大好处,因为我们仍然需要一个索引。我们真的希望能够直接从循环中获取字典键和字典值。而且,瞧瞧,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 comprehension
dictData = {key.value: value.value for key, value in zip(ws1[3][2:], ws1[5][2:])}
最后两个都可以,我会说,尽管我更喜欢听写理解,因为我发现它很容易阅读,但你的里程数可能会有所不同。
此外,作为最后一点,为了让代码感觉更像 pythonic,请将驼峰式 dictData
替换为更符合 PEP8 的形式 dict_data
。但这当然只有在项目中的所有变量都使用该样式时才是正确的。保持一致更重要。
刚刚查看了您的共享数据;因为您只对两行(第 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