生成 A1 引用样式列名称的最惯用的方法是什么?
What is the most idiomatic way of generating A1 reference style column names?
我正在尝试创建一个算法来隐式处理每个可能的单元格标识符;使用 A1 参考样式。 A1 引用样式通常限于列 (A - IV) 和行 (0 - 65,536)。这是用于生成 Excel 和数字电子表格的格式。我明白为什么会有这些限制,但我正试图用“正确”的方式来命名列;程序上。更具体地说,我试图了解如何在程序上为每一列生成正确的名称。结果将是一个包含列 A-Z、AA-ZZ、AAA-ZZZ 等的字典。此“电子表格”的单元格类似于 AHD129、A1 或 XAPRC100204。
一切都是从尝试生成棋盘的单元格开始的,这相对容易:
board = {}
for file in 'ABCDEFGH':
for rank in range(0, 8):
cell = file + str(rank + 1)
board[cell] = ''
这会处理棋盘 (A1 - H8) 的每个组合,并将其全部放入字典中。问题是它非常明确。
我们可以隐式处理所有可能的组合 (A1 - Z26),就像这样...
def generate(units):
cells = {}
alphabet = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
for column in range(0, units):
char = alphabet[column]
for row in range(0, units):
cell = char + str(row + 1)
cells[cell] = ''
return cells
这样更好,因为它允许我们在给定范围 (A1-Z26) 内生成“棋盘”。您可以将 1 到 26 之间的任何整数传递给此函数,但当 (units > 26) 时将抛出错误。
如果我们将“棋盘”除以 27 个单元,那么我们需要生成 (A1-AA27)。
单位 = 1 -> 26 |结果 A1 - Z26
单位 = 1 -> 52 |结果 A1 - AZ52
单位 = 1 -> 78 |结果 A1 - BZ78
单位 = 1 -> 104|结果 A1 - CZ104
我的数学可能有几个整数偏差,但我基本上只是想创建一个正方形的表示。列和行总是相等的,这就是为什么我用嵌套的 for 循环来处理这个问题。我知道我可以写一个巨大的条件块来处理每个 26 的范围,超出最初的 26 个字符,比如:
if column in range(0, len(alphabet)):
char = alphabet[i]
elif column in range(len(alphabet), len(alphabet) * 2):
char = 'A' + alphabet[i]
elif column in range(len(alphabet) * 2, len(alphabet) * 3):
char = 'B' + alphabet[i]
...但这有违直觉。我正在尝试处理任意整数(例如:1,000,000 或 63,432)。我假设(welp)它与通过 while 循环“暴力破解”列名有关,但我也知道这是 Python。也就是说,有一种我以前从未遇到过的非常简单的方法可以解决这个问题。
我不想让任何人为我“编写我的代码”,但是有人可以给我指出正确的方向吗?如何以 A1 参考样式 电子表格格式按程序生成列名称? 最好的 从给定的字符列表 Python 构造字符串的方法是什么?
请不要建议一个库来解决这个问题,因为我正在尝试了解底层解决方案。对于任何不正确的术语,我深表歉意,如果我使用的任何内容不正确,请更正我的话。任何帮助或考虑,将不胜感激。我非常愿意为未来的观众修改整个问题。
How to create a function that converts a Number to a Bijective Hexavigesimal?
编码称为 bijective-base 26。或者您可以使用上面堆栈溢出中使用的基数 26 的奇特术语 post。实际上,解码真的很容易。 ABC = 1 * 26 * 26 + 2 * 26 + 3。将数字视为以 26 为底数,但 A=1、Z=26 而不是 A=0、Z=25。
==更新==
现在想想,反方向也很容易。 26进制转换的标准算法是你反复除以26,余数给你的数位倒序。
这个算法,重复前面的商减去1除以26,余数,当0-25转化为A-Z,答案在倒序。
#convert 65536
divmod(65535, 26)
(2520, 15)
>>> divmod(2519, 26)
divmod(2519, 26)
(96, 23)
>>> divmod(95, 26)
divmod(95, 26)
(3, 17)
>>> divmod(2, 16)
divmod(2, 16)
(0, 2)
# The remainders in reverse order are 2,17,23,15 -> CRXP
我回来了;报仇雪恨。我找不到最惯用的方法来做到这一点,但我确实想出了一个天真的方法来生成 A1 参考样式网格。您可以为宽度或高度参数输入任何大于零的整数。
def generate_cells(width, height):
"""Generates cell-names for an 'A1 Reference Style' grid,
and places them into a dictionary with empty values.
width and height parameters are both = integer > zero"""
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # explicit to avoid import
empty_grid = {}
for column in range(1, width+1):
bijective_hexavigesimal = []
while column: # repetitiously reduce unit with divmod()
column, remainder = divmod(column - 1, 26)
bijective_hexavigesimal[:0] = alphabet[remainder]
column = ''.join(bijective_hexavigesimal)
for row in range(1, height+1):
cell = column + str(row)
empty_grid[cell] = ''
return empty_grid
Returns 具有空字符串值的键的字典...享受吧。
我正在尝试创建一个算法来隐式处理每个可能的单元格标识符;使用 A1 参考样式。 A1 引用样式通常限于列 (A - IV) 和行 (0 - 65,536)。这是用于生成 Excel 和数字电子表格的格式。我明白为什么会有这些限制,但我正试图用“正确”的方式来命名列;程序上。更具体地说,我试图了解如何在程序上为每一列生成正确的名称。结果将是一个包含列 A-Z、AA-ZZ、AAA-ZZZ 等的字典。此“电子表格”的单元格类似于 AHD129、A1 或 XAPRC100204。
一切都是从尝试生成棋盘的单元格开始的,这相对容易:
board = {}
for file in 'ABCDEFGH':
for rank in range(0, 8):
cell = file + str(rank + 1)
board[cell] = ''
这会处理棋盘 (A1 - H8) 的每个组合,并将其全部放入字典中。问题是它非常明确。
我们可以隐式处理所有可能的组合 (A1 - Z26),就像这样...
def generate(units):
cells = {}
alphabet = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
for column in range(0, units):
char = alphabet[column]
for row in range(0, units):
cell = char + str(row + 1)
cells[cell] = ''
return cells
这样更好,因为它允许我们在给定范围 (A1-Z26) 内生成“棋盘”。您可以将 1 到 26 之间的任何整数传递给此函数,但当 (units > 26) 时将抛出错误。 如果我们将“棋盘”除以 27 个单元,那么我们需要生成 (A1-AA27)。
单位 = 1 -> 26 |结果 A1 - Z26
单位 = 1 -> 52 |结果 A1 - AZ52
单位 = 1 -> 78 |结果 A1 - BZ78
单位 = 1 -> 104|结果 A1 - CZ104
我的数学可能有几个整数偏差,但我基本上只是想创建一个正方形的表示。列和行总是相等的,这就是为什么我用嵌套的 for 循环来处理这个问题。我知道我可以写一个巨大的条件块来处理每个 26 的范围,超出最初的 26 个字符,比如:
if column in range(0, len(alphabet)):
char = alphabet[i]
elif column in range(len(alphabet), len(alphabet) * 2):
char = 'A' + alphabet[i]
elif column in range(len(alphabet) * 2, len(alphabet) * 3):
char = 'B' + alphabet[i]
...但这有违直觉。我正在尝试处理任意整数(例如:1,000,000 或 63,432)。我假设(welp)它与通过 while 循环“暴力破解”列名有关,但我也知道这是 Python。也就是说,有一种我以前从未遇到过的非常简单的方法可以解决这个问题。
我不想让任何人为我“编写我的代码”,但是有人可以给我指出正确的方向吗?如何以 A1 参考样式 电子表格格式按程序生成列名称? 最好的 从给定的字符列表 Python 构造字符串的方法是什么?
请不要建议一个库来解决这个问题,因为我正在尝试了解底层解决方案。对于任何不正确的术语,我深表歉意,如果我使用的任何内容不正确,请更正我的话。任何帮助或考虑,将不胜感激。我非常愿意为未来的观众修改整个问题。
How to create a function that converts a Number to a Bijective Hexavigesimal?
编码称为 bijective-base 26。或者您可以使用上面堆栈溢出中使用的基数 26 的奇特术语 post。实际上,解码真的很容易。 ABC = 1 * 26 * 26 + 2 * 26 + 3。将数字视为以 26 为底数,但 A=1、Z=26 而不是 A=0、Z=25。
==更新==
现在想想,反方向也很容易。 26进制转换的标准算法是你反复除以26,余数给你的数位倒序。
这个算法,重复前面的商减去1除以26,余数,当0-25转化为A-Z,答案在倒序。
#convert 65536
divmod(65535, 26)
(2520, 15)
>>> divmod(2519, 26)
divmod(2519, 26)
(96, 23)
>>> divmod(95, 26)
divmod(95, 26)
(3, 17)
>>> divmod(2, 16)
divmod(2, 16)
(0, 2)
# The remainders in reverse order are 2,17,23,15 -> CRXP
我回来了;报仇雪恨。我找不到最惯用的方法来做到这一点,但我确实想出了一个天真的方法来生成 A1 参考样式网格。您可以为宽度或高度参数输入任何大于零的整数。
def generate_cells(width, height):
"""Generates cell-names for an 'A1 Reference Style' grid,
and places them into a dictionary with empty values.
width and height parameters are both = integer > zero"""
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # explicit to avoid import
empty_grid = {}
for column in range(1, width+1):
bijective_hexavigesimal = []
while column: # repetitiously reduce unit with divmod()
column, remainder = divmod(column - 1, 26)
bijective_hexavigesimal[:0] = alphabet[remainder]
column = ''.join(bijective_hexavigesimal)
for row in range(1, height+1):
cell = column + str(row)
empty_grid[cell] = ''
return empty_grid
Returns 具有空字符串值的键的字典...享受吧。