2016-09-19 2 views
0

У меня есть два итератора на питоне, и оба должны следовать одному и тому же «случайному» распределению (оба должны работать параллельно). Например:Параллельное случайное распределение

class Iter1(object): 
    def __iter__(self): 
     for i in random_generator(): 
      yield i 

class Iter2(object): 
    def __iter__(self): 
     for i in random_generator(): 
      yield i 

for el1, el2 in zip(Iter1(), Iter2()): 
    print '{} {}'.format(el1, el2) 

выход должен быть somethig как:

0.53534 0.53534 
0.12312 0.12312 
0.19238 0.19238 

Как я могу определить random_generator() таким образом, что она создает те же самые случайные распределения в параллельном для обоих итераторы.

Примечание:

  • Они должны работать параллельно
  • Я не могу генерировать последовательность заранее (это потоковый, так что я не знаю размер последовательности)

Спасибо.

+0

Просто присвоить один выход к переменной и использовать эту переменную дважды – iScrE4m

+0

Если вам нужны две копии одного и того же итерации, используйте 'itertools.tee' – jonrsharpe

+0

Почему бы не генерировать один и скопировать его в другую? – Jeon

ответ

2

указать те же семена для каждого вызова random_generator:

import random 

def random_generator(l, seed=None): 
    r = random.Random(seed) 
    for i in range(l): 
     yield r.random() 


class Iter1(object): 
    def __init__(self, seed): 
     self.seed = seed 

    def __iter__(self): 
     for i in random_generator(10, self.seed): 
      yield i 


class Iter2(object): 
    def __init__(self, seed): 
     self.seed = seed 
    def __iter__(self): 
     for i in random_generator(10, self.seed): 
      yield i 


# The seed can be any hashable object, but don't use None; that 
# tells random.seed() to use the current time. But make sure that 
# Python itself isn't using hash randomization. 
common_seed = object() 
for el1, el2 in zip(Iter1(common_seed), Iter2(common_seed)): 
    print '{} {}'.format(el1, el2) 
+0

Вы уверены, что это сработало? Я ожидал бы получить разные числа от каждого, потому что они берут числа из одного и того же базового потока случайных чисел. – jonrsharpe

+0

Когда я начал, я не собирался использовать глобальную функцию 'random' и создавать экземпляр нового объекта« Random », но потом был взволнован, когда заметил, что« семя »также является глобальной функцией. Я должен повторить это. – chepner

+0

Я не вижу причин объявлять два класса «Iter» здесь - почему бы просто не создать два экземпляра «Iter1» с одним и тем же семенем? –

0

Таким образом невозможно управлять случайным числом генерации. Если вы хотите сделать это, вы должны создать свою собственную случайную функцию. Но как еще один вещий и более простым способом вы можете просто создать один объект и использовать itertools.tee для того, чтобы скопировать объект итератора к иметь тот же результат для ваших случайных последовательностей:

In [28]: class Iter1(object): 
      def __init__(self, number): 
       self.number = number 
      def __iter__(self): 
       for _ in range(self.number): 
        yield random.random() 
    ....:     

In [29]: 

In [29]: num = Iter1(5) 

In [30]: from itertools import tee 

In [31]: num, num2 = tee(num) 

In [32]: list(zip(num, num2)) 
Out[32]: 
[(0.485400998727448, 0.485400998727448), 
(0.8801649381536764, 0.8801649381536764), 
(0.9684025615967844, 0.9684025615967844), 
(0.9980073706742334, 0.9980073706742334), 
(0.1963579685642387, 0.1963579685642387)] 
Смежные вопросы