重复像excel列的字母?
我想创build一个类似于Microsoft Excel中的列字母的string列表。 例如,在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'), ...
将它与第一组字母组合起来,并将这些对join:
>>> 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']
概括来说,我们定义一个发电机,build立越来越大的产品。 请注意,yield只能在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]] * (li-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', ... ]
它从当前生成下一个string:
-
从后面查找不是字母表中最后一个的第一个字符:例如
!= 'Z'
b)增加它:将其设置为下一个字母
c)将所有后续字符重置为第一个字母字符
-
如果没有find这样的可递增字符,则从全部首字母开始,将长度增加
1
人们可以写一个更可读/全面的函数,代价是(更多)更大的内存占用,尤其是在生成许多标签的情况下:
def labels(alphabet=string.ascii_uppercase): agenda = deque(alphabet) while agenda: s = agenda.popleft() yield s agenda.append([s+c for c in alphabet])
基于这个答案: https : //stackoverflow.com/a/182009/6591347
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
我的解决scheme
itertools.chain(*[itertools.product(map(chr, range(65,91)), repeat=i) for i in xrange(1, 10)])
请注意魔术数字10 – 这是列名中的最大字母。
说明:
首先创buildAZ列表作为列表:
map(chr, range(65,91))
然后使用产品创build组合(长度从1开始到10结束)
itertools.product(map(chr, range(65,91)), repeat=i)
最后使用itertools.chain
所有这些生成器连接成单个生成器
在Excel中,使用公式,在单元格A1中input:
=SUBSTITUTE(SUBSTITUTE(ADDRESS(1,ROW()),"$",""),"1","")
并向下复制。
这将是有效的第一个16384项目