如何生成用于网格坐标的字母列表?(比如 a, b,...,z, aa, bb,...,zz, aaa等)

2 投票
5 回答
1109 浏览
提问于 2025-04-17 12:47

基本上就是标题所说的。我找不到生成字母的方法。我需要这个是因为我正在为游戏“战舰”写一些代码,所以我打算用它来定义一个网格。

5 个回答

0

这个内容跟amber的回答差不多;不过它会生成一个超级大的列表,里面包含了所有一、二、三字母的组合,并且这些组合是按顺序排列的。如果你想要更长的组合,只需要把range(1,4)中的4改大就可以了。

import string
import itertools
ordered_abc_list = reduce(lambda x,y:x+y,
                          map(lambda N:[''.join(x) for x in itertools.product(string.lowercase, repeat=N)],
                              range(1,4)
                              )
                          )

如果你更喜欢创建一个生成器,而不是一个列表的话:

ordered_generator = (''.join(s) for s in
                        itertools.chain(*map(lambda N:itertools.product(string.lowercase, repeat=N), 
                                             range(1,4)
                                             )
                                        )
                     )

这个生成器可以像这样使用:

for x in ordered_generator:
    print x
1

这里有一个通用的解决方案,使用的是进制转换。这是受到Steven Rumbalski评论的启发;可以用它来把数字转换成字母标识。它不会生成aa, ab..这样的组合,因为它把a当作0来处理。从这个意义上说,这可能不是你想要的,但我更喜欢这种方式;它使用了一种更一致的表达方式。

>>> from string import lowercase
>>> def base_26_gen(x):
...     if x == 0: yield x
...     while x > 0:
...         yield x % 26
...         x //= 26
... 
>>> def base_26_chr(x):
...     return ''.join(lowercase[i] for i in reversed(list(base_26_gen(x))))
... 
>>> [base_26_chr(x) for x in range(100)]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 
 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'ba', 'bb', 'bc', 'bd', 'be', 
 'bf', 'bg', 'bh', 'bi', 'bj', 'bk', 'bl', 'bm', 'bn', 'bo', 'bp', 'bq', 'br', 
 'bs', 'bt', 'bu', 'bv', 'bw', 'bx', 'by', 'bz', 'ca', 'cb', 'cc', 'cd', 'ce', 
 'cf', 'cg', 'ch', 'ci', 'cj', 'ck', 'cl', 'cm', 'cn', 'co', 'cp', 'cq', 'cr', 
 'cs', 'ct', 'cu', 'cv', 'cw', 'cx', 'cy', 'cz', 'da', 'db', 'dc', 'dd', 'de', 
 'df', 'dg', 'dh', 'di', 'dj', 'dk', 'dl', 'dm', 'dn', 'do', 'dp', 'dq', 'dr', 
 'ds', 'dt', 'du', 'dv']

反向操作会简单一些:

>>> def b26_chr_to_b10(x):
...     return sum((ord(c) - 97) * 26 ** i for i, c in enumerate(reversed(x)))
... 
>>> b26_chr_to_b10('ab')
1
>>> b26_chr_to_b10('ba')
26
2
import string
import itertools
one_letter_items = list(string.lowercase)
two_letter_items = [''.join(x) for x in
    itertools.product(string.lowercase, repeat=2)]

items = one_letter_items + two_letter_items

或者更简洁的写法:

items = list(string.lowercase) + [''.join(x) for x in itertools.product(string.lowercase, repeat=2)]

你可以继续用同样的方法添加更长的字符串,只需要再次调用 itertools.product(),并增加 repeat 的值(不过我不知道为什么在“战舰”游戏中需要超过702列)。

如果你不打算使用 所有 字母,可以通过使用生成器来提高效率:

items = itertools.chain(string.lowercase, (''.join(x) for x in itertools.product(string.lowercase, repeat=2)))

撰写回答