我想生成一个大小为N的字符串。
它应该由数字和大写英文字母组成,例如:
- 6U1S75
- 4Z4UKK
- U911K4
我如何以pythonic方式实现这一目标?
#1楼
如果您需要一个随机字符串而不是伪随机字符串,则应使用os.urandom
作为源
from os import urandom
from itertools import islice, imap, repeat
import string
def rand_string(length=5):
chars = set(string.ascii_uppercase + string.digits)
char_gen = (c for c in imap(urandom, repeat(1)) if c in chars)
return ''.join(islice(char_gen, None, length))
#2楼
与Ignacio发布的random.choice()方法相比,此方法稍快一些,但也更令人讨厌。
它利用了伪随机算法的特性,并且比按每个字符生成一个新的随机数更快地按位和移位。
# must be length 32 -- 5 bits -- the question didn't specify using the full set
# of uppercase letters ;)
_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
def generate_with_randbits(size=32):
def chop(x):
while x:
yield x & 31
x = x >> 5
return ''.join(_ALPHABET[x] for x in chop(random.getrandbits(size * 5))).ljust(size, 'A')
...创建一个在0..31的时间里取出5位数字的生成器,直到没有剩余
... join()生成器的结果在具有正确位的随机数上
使用Timeit,对于32个字符的字符串,计时为:
[('generate_with_random_choice', 28.92901611328125),
('generate_with_randbits', 20.0293550491333)]
...但是对于64个字符串,randbit会失败;)
除非我真的不喜欢我的同事,否则我可能永远不会在生产代码中使用这种方法。
编辑:已更新以适合该问题(仅适用于大写字母和数字),并使用按位运算符&和>>代替%和//
#3楼
只需使用Python的内置uuid:
如果您可以使用UUID,请使用内置的uuid软件包。
一线解决方案:
import uuid; uuid.uuid4().hex.upper()[0:6]
深度版本:
例:
import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')
如果您确实需要格式(例如“ 6U1S75”),则可以这样做:
import uuid
def my_random_string(string_length=10):
"""Returns a random string of length string_length."""
random = str(uuid.uuid4()) # Convert UUID format to a Python string.
random = random.upper() # Make all characters uppercase.
random = random.replace("-","") # Remove the UUID '-'.
return random[0:string_length] # Return the random string.
print(my_random_string(6)) # For example, D9E50C
#4楼
根据另一个Stack Overflow答案, 创建随机字符串和随机十六进制数的最轻巧的方法,比公认的答案更好的版本是:
('%06x' % random.randrange(16**6)).upper()
快多了。
#5楼
>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be? '))
How long do you want the string to be? 10
>>> for k in range(1, num+1):
... str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'
random.choice
函数从列表中选择一个随机条目。 您还创建一个列表,以便可以将字符追加到for
语句中。 最后的str是['t','m','2','J','U','Q','0','4','C','K'],但是str = "".join(str)
负责此工作,剩下'tm2JUQ04CK'
。
希望这可以帮助!
#6楼
一行回答:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
甚至更短,使用random.choices()
从Python 3.6开始:
''.join(random.choices(string.ascii_uppercase + string.digits, k=N))
加密更安全的版本; 参见https://stackoverflow.com/a/23728630/2213647 :
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
详细而言,具有清除函数以进一步重用