Для тех из вас, кто любит функциональный питон:
from itertools import imap, starmap, islice, repeat
from functools import partial
from string import letters, digits, join
from random import choice
join_chars = partial(join, sep='')
identity = lambda o: o
def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
""" Generates an indefinite sequence of joined random symbols each of a specific length
:param symbols: symbols to select,
[defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
:param length: the length of each sequence,
[defaults to 6]
:param join: method used to join selected symbol,
[defaults to ''.join generating a string.]
:param select: method used to select a random element from the giving population.
[defaults to random.choice, which selects a single element randomly]
:return: indefinite iterator generating random sequences of giving [:param length]
>>> from tools import irand_seqs
>>> strings = irand_seqs()
>>> a = next(strings)
>>> assert isinstance(a, (str, unicode))
>>> assert len(a) == 6
>>> assert next(strings) != next(strings)
"""
return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))
Он генерирует неопределенный [бесконечный] итератор из соединенных случайных последовательностей, сначала генерируя неопределенную последовательность случайно выбранных символов из пула-получателя,затем разбивая эту последовательность на части длины, которые затем соединяются, она должна работать с любой последовательностью, поддерживающей getitem, по умолчанию она просто генерирует случайную последовательность буквенно-цифровых букв, хотя вы можете легко изменить ее для генерации других вещей:
например, для генерации случайных наборов цифр:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> next(irand_tuples)
(0, 5, 5, 7, 2, 8)
>>> next(irand_tuples)
(3, 2, 2, 0, 3, 1)
, если вы не хотите использовать следующее поколение, вы можете просто сделать его вызываемым:
>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples)
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)
, если вы хотитегенерируйте последовательность на лету, просто установите соединение с идентификатором.
>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]
Как уже упоминали другие, если вам нужна дополнительная безопасность, установите соответствующую функцию выбора:
>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'
селектор по умолчанию -choice
, который может выбрать один и тот же символ несколько раз для каждого чанка, если вместо этого вы хотитеодин и тот же элемент выбирается не более одного раза для каждого чанка, затем возможное использование:
>>> from random import sample
>>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
>>> next(irand_samples)
[0, 9, 2, 3, 1, 6]
мы используем sample
в качестве нашего селектора, чтобы сделать полный выбор, так что чанки фактически имеют длину 1 и присоединяютсямы просто вызываем next
, который выбирает следующий полностью сгенерированный кусок, при условии, что этот пример кажется немного громоздким, и это ...