重复 excel 列之类的字母?
Repeating letters like excel columns?
我想创建一个字符串列表,类似于 Microsoft Excel 中的列字母。例如,在 26 列之后,接下来的列变为 AA
、AB
、AC
等
我试过使用取模运算符,但我最后得到的是 AA
、BB
、CC
等...
import string
passes_through_alphabet = 0
for num, col in enumerate([_ for _ in range(40)]):
if num % 26 == 0:
passes_through_alphabet += 1
excel_col = string.ascii_uppercase[num%26] * passes_through_alphabet
print(num, excel_col)
0 A
1 B
2 C
3 D
...
22 W
23 X
24 Y
25 Z
26 AA
27 BB
28 CC
...
您可以为此使用 itertools.product:
>>> import itertools
>>> list(itertools.product(string.ascii_uppercase, repeat=2))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ...
将其与第一组字母组合,并加入成对结果:
>>> list(
... itertools.chain(
... string.ascii_uppercase,
... (''.join(pair) for pair in itertools.product(string.ascii_uppercase, repeat=2))
... ))
['A', 'B', 'C', .. 'AA', 'AB', 'AC' .. 'ZZ']
总而言之,我们定义了一个生成器来构建越来越大的产品。请注意,yield from 仅在 python 3.3+ 中可用,但如果您使用的是 python 2.
,则可以只使用 for 循环来生成每个项目
>>> def excel_cols():
...: n = 1
...: while True:
...: yield from (''.join(group) for group in itertools.product(string.ascii_uppercase, repeat=n))
...: n += 1
>>> list(itertools.islice(excel_cols(), 28))
['A',
'B',
'C',
...
'X',
'Y',
'Z',
'AA',
'AB']
此生成器函数适用于任意字母表:
import string
def labels(alphabet=string.ascii_uppercase):
assert len(alphabet) == len(set(alphabet)) # make sure every letter is unique
s = [alphabet[0]]
while 1:
yield ''.join(s)
l = len(s)
for i in range(l-1, -1, -1):
if s[i] != alphabet[-1]:
s[i] = alphabet[alphabet.index(s[i])+1]
s[i+1:] = [alphabet[0]] * (l-i-1)
break
else:
s = [alphabet[0]] * (l+1)
> x = labels(alphabet='ABC')
> print([next(x) for _ in range(20)])
['A', 'B', 'C', 'AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC', 'AAA', 'AAB', ... ]
它从当前字符串生成下一个字符串:
从字母表中不是最后一个的后面查找第一个字符:例如!= 'Z'
b) 递增:设置为下一个字母
c) 将所有后续字符重置为第一个字母字符
如果找不到这样的可递增字符,则从所有第一个字母开始,将长度增加 1
可以编写更多 readable/comprehensive 函数,但会占用(多得多)更大的内存空间,尤其是在生成许多标签的情况下:
def labels(alphabet=string.ascii_uppercase):
agenda = deque(alphabet)
while agenda:
s = agenda.popleft()
yield s
agenda.append([s+c for c in alphabet])
基于这个答案:
def num_to_excel_col(n):
if n < 1:
raise ValueError("Number must be positive")
result = ""
while True:
if n > 26:
n, r = divmod(n - 1, 26)
result = chr(r + ord('A')) + result
else:
return chr(n + ord('A') - 1) + result
我的解决方案:
itertools.chain(*[itertools.product(map(chr, range(65,91)), repeat=i) for i in xrange(1, 10)])
请注意幻数 10 - 这是列名称中的最大字母数。
说明:
首先创建 A-Z 个字母作为列表:
map(chr, range(65,91))
然后使用产品创建组合(长度从 1 开始到 10 结束)
itertools.product(map(chr, range(65,91)), repeat=i)
最后使用 itertools.chain
将所有这些生成器连接成一个生成器
我想创建一个字符串列表,类似于 Microsoft Excel 中的列字母。例如,在 26 列之后,接下来的列变为 AA
、AB
、AC
等
我试过使用取模运算符,但我最后得到的是 AA
、BB
、CC
等...
import string
passes_through_alphabet = 0
for num, col in enumerate([_ for _ in range(40)]):
if num % 26 == 0:
passes_through_alphabet += 1
excel_col = string.ascii_uppercase[num%26] * passes_through_alphabet
print(num, excel_col)
0 A
1 B
2 C
3 D
...
22 W
23 X
24 Y
25 Z
26 AA
27 BB
28 CC
...
您可以为此使用 itertools.product:
>>> import itertools
>>> list(itertools.product(string.ascii_uppercase, repeat=2))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ...
将其与第一组字母组合,并加入成对结果:
>>> list(
... itertools.chain(
... string.ascii_uppercase,
... (''.join(pair) for pair in itertools.product(string.ascii_uppercase, repeat=2))
... ))
['A', 'B', 'C', .. 'AA', 'AB', 'AC' .. 'ZZ']
总而言之,我们定义了一个生成器来构建越来越大的产品。请注意,yield from 仅在 python 3.3+ 中可用,但如果您使用的是 python 2.
,则可以只使用 for 循环来生成每个项目 >>> def excel_cols():
...: n = 1
...: while True:
...: yield from (''.join(group) for group in itertools.product(string.ascii_uppercase, repeat=n))
...: n += 1
>>> list(itertools.islice(excel_cols(), 28))
['A',
'B',
'C',
...
'X',
'Y',
'Z',
'AA',
'AB']
此生成器函数适用于任意字母表:
import string
def labels(alphabet=string.ascii_uppercase):
assert len(alphabet) == len(set(alphabet)) # make sure every letter is unique
s = [alphabet[0]]
while 1:
yield ''.join(s)
l = len(s)
for i in range(l-1, -1, -1):
if s[i] != alphabet[-1]:
s[i] = alphabet[alphabet.index(s[i])+1]
s[i+1:] = [alphabet[0]] * (l-i-1)
break
else:
s = [alphabet[0]] * (l+1)
> x = labels(alphabet='ABC')
> print([next(x) for _ in range(20)])
['A', 'B', 'C', 'AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC', 'AAA', 'AAB', ... ]
它从当前字符串生成下一个字符串:
从字母表中不是最后一个的后面查找第一个字符:例如
!= 'Z'
b) 递增:设置为下一个字母
c) 将所有后续字符重置为第一个字母字符
如果找不到这样的可递增字符,则从所有第一个字母开始,将长度增加
1
可以编写更多 readable/comprehensive 函数,但会占用(多得多)更大的内存空间,尤其是在生成许多标签的情况下:
def labels(alphabet=string.ascii_uppercase):
agenda = deque(alphabet)
while agenda:
s = agenda.popleft()
yield s
agenda.append([s+c for c in alphabet])
基于这个答案:
def num_to_excel_col(n):
if n < 1:
raise ValueError("Number must be positive")
result = ""
while True:
if n > 26:
n, r = divmod(n - 1, 26)
result = chr(r + ord('A')) + result
else:
return chr(n + ord('A') - 1) + result
我的解决方案:
itertools.chain(*[itertools.product(map(chr, range(65,91)), repeat=i) for i in xrange(1, 10)])
请注意幻数 10 - 这是列名称中的最大字母数。
说明:
首先创建 A-Z 个字母作为列表:
map(chr, range(65,91))
然后使用产品创建组合(长度从 1 开始到 10 结束)
itertools.product(map(chr, range(65,91)), repeat=i)
最后使用 itertools.chain