В Python относительно легко иметь бесконечный массив с использованием генераторов, а также произвольно длинных, лениво вычисляемых и т. Д. Что бы вы хотели сделать, чтобы сопоставить подобные вещи с ключами, это иметь бесконечно длинный , лениво оцененный список или генератор .
import itertools
import string
Сначала вы хотите itertools, который имеет множество удобных функций для манипулирования массивами бесконечного размера. строка содержит несколько стандартных строковых констант.
def lower_then_upper():
return iter(string.letters)
iter
здесь строго не требуется, но для согласованности он превратит стандартный список в генератор.
def get_n(n=2):
generators = []
for gen in range(n):
generators.append(lower_then_upper())
tuples = itertools.product(*generators)
return itertools.imap(''.join, tuples)
Здесь мы начинаем собирать вещи, эта функция будет возвращать список строк фиксированной длины, составленный из букв. Строка за строкой, биты перед tuples
обеспечивают наличие генератора для всех строк, доступных для каждой буквенной позиции. т.е. три списка a-Z будут созданы, если n = 3.
Ниже itertools.product
делает декартово произведение всех доступных вещей, которое в Python, к счастью, повторяет последнее первым, так что вы получите для n = 2: `['aa', 'ab', ..., 'ZX', 'ZY', 'ZZ']
.
В последней строке itertools.imap
применяется функция ''.join
к каждому элементу в кортежах. До сих пор они имели форму (('a', 'a'), ('a', 'b'), …
, это гарантирует, что они являются строкой, так же, как ''.join(['a', 'a']) == 'aa'
.
def get_infinite():
n = 0
while True:
n += 1
for item in get_n(n):
yield item
Здесь происходит волшебство. Он исчерпает итератор для n = 1, а затем исчерпает n = 2 и т. Д.
def inf_hello():
while True:
yield "hello world"
Это просто демонстрационный бесконечный список
mapped = itertools.izip(get_infinite(), inf_hello())
Теперь мы объединяем их вместе, чтобы получить бесконечный массив пар ключ / значение:
>>> list(itertools.islice(mapped, 1000, 1010))
[('sm', 'hello world'), ('sn', 'hello world'), ('so', 'hello world'), ('sp', 'hello world'), ('sq', 'hello world'), ('sr', 'hello world'), ('ss', 'hello world'), ('st', 'hello world'), ('su', 'hello world'), ('sv', 'hello world')]
как мы видим, если мы интроспектируем это 1000 элементов в.
В качестве альтернативы, мы можем дать ему длинный список и получить словарь:
>>> numbers = dict(itertools.izip(get_infinite(), range(0, 10000)))
>>> print numbers['a'], numbers['aa'], numbers['caW']
0 52 8212
Надеюсь, это поможет.