一尘不染

使用大写字母和数字生成随机字符串

python

我想生成一个大小为 N 的字符串。

它应该由数字和大写英文字母组成,例如:

  • 6U1S75
  • 4Z4UKK
  • U911K4

我怎样才能以pythonic方式实现这一点?


阅读 167

收藏
2022-02-21

共1个答案

一尘不染

一句话回答:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

从 Python 3.6 开始甚至更短,使用random.choices()

''.join(random.choices(string.ascii_uppercase + string.digits, k=N))

加密更安全的版本: 请参阅这篇文章

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

详细地说,带有一个干净的功能以供进一步重用:

>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...    return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'

它是如何工作的 ?

我们导入string一个包含常见 ASCII 字符序列的random模块和一个处理随机生成的模块。

string.ascii_uppercase + string.digits只是连接代表大写 ASCII 字符和数字的字符列表:

>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

然后我们使用列表推导来创建一个包含“n”个元素的列表:

>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']

在上面的示例中,我们使用[创建列表,但我们没有在id_generator函数中创建列表,因此 Python 不会在内存中创建列表,而是动态生成元素,一个一个一个(更多关于这里)。

我们将要求 Python 创建 ‘n’ 次随机字符,而不是要求创建 ‘n’ 次字符串elem,该随机字符是从一系列字符中挑选出来的:

>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'

因此random.choice(chars) for _ in range(size)真的是在创建一个size字符序列。随机抽取的字符chars

>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']

然后我们将它们与一个空字符串连接起来,这样序列就变成了一个字符串:

>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'
2022-02-21