Я ищу чистый способ сделать это в Python:
Скажем, у меня есть два итератора "iter1" и "iter2": возможно, генератор простых чисел и itertools.count(). Я знаю априори, что оба они бесконечны и монотонно возрастают. Теперь я хочу сделать несколько простых операций с двумя аргументами "op" (возможно, operator.add или operator.mul) и вычислить каждый элемент первого итератора с каждым элементом следующего, используя указанную операцию, затем выведите их по одному, отсортированные. Очевидно, что это бесконечная последовательность. (Как упоминалось в комментарии @RyanThompson: это будет называться Декартовым продуктом этих последовательностей... или, точнее, 1d-сортировка этого продукта.)
Каков наилучший способ:
- обертывание "iter1", "iter2" и "op" в итерабельном, которое само приводит к значениям в монотонно увеличивающемся выходе.
Допустимые упрощающие предположения:
- Если это помогает, мы можем считать op (a, b) >= a и op (a, b) >= b.
- Если это помогает, мы можем считать op (a, b) > op (a, c) для всех b > c.
Также допустимо:
- Также допустимым будет итератор, который дает значения в "обычно увеличивающемся" порядке... под которым я имею в виду, что итерабельность иногда может дать мне число меньше предыдущего, но оно каким-то образом сделает доступной "дополнительную информацию" ( как с помощью метода на объекте), который сказал бы: "Я не гарантирую следующее значение, которое я вам даю, будет больше, чем тот, который я вам только что дал, но я УВЕРЕН, что все будущие значения будут, по крайней мере, больше N.".... и "N" монотонно возрастает.
Единственный способ, которым я могу это сделать, - это своего рода процесс "диагонализации", в котором я постоянно увеличиваю количество частично обработанных итераций и "смотрю вперед" на минимум всех возможных следующих() значений, и это даст. Но эта странная агломерация heapq и кучка deques просто кажется диковинной, даже до того, как я начну ее кодировать.
Пожалуйста: не основывайте свой ответ на том факте, что в моих примерах указаны простые числа или count().... У меня есть несколько применений для этой самой концепции, которые НЕ относятся к простым числам и count().
ОБНОВЛЕНИЕ: OMG! Какая отличная дискуссия! И некоторые отличные ответы с действительно подробными объяснениями. Спасибо. StackOverflow пород; вы, ребята, рок.
Я собираюсь углубиться в каждый ответ более подробно в ближайшее время и дать образец кода ударом по шинам. Из того, что я читал до сих пор, мои первоначальные подозрения подтверждаются тем, что для этого нет "простой идиомы Python". Скорее, так или иначе, я не могу избежать сохранения всех полученных значений iter1 и iter2 неограниченно.
FWIW: здесь официальный "тестовый пример", если вы хотите попробовать свои решения.
import operator
def powers_of_ten():
n = 0
while True:
yield 10**n
n += 1
def series_of_nines():
yield 1
n = 1
while True:
yield int("9"*n)
n += 1
op = operator.mul
iter1 = powers_of_ten()
iter2 = series_of_nines()
# given (iter1, iter2, op), create an iterator that yields:
# [1, 9, 10, 90, 99, 100, 900, 990, 999, 1000, 9000, 9900, 9990, 9999, 10000, ...]