简体   繁体   English

为什么 itertools.repeat 总是生成相同的随机数?

[英]Why `itertools.repeat` always generate the same random number?

Compare the outputs of these two functions:比较这两个函数的输出:

from itertools import repeat
def rand_list1():
    l = lambda: np.random.rand(3)
    return list(repeat(l(), 5))

def rand_list2():
    return [np.random.rand(3) for i in range(5)]

We see that rand_list1 who uses itetools.repeat always generates the same 3 numbers.我们看到使用rand_list1itetools.repeat总是生成相同的 3 个数字。 why is this?为什么是这样? Can it be avoided, so each call of rand_list() will generate new numbers?是否可以避免,所以每次调用rand_list()都会生成新数字?

For example, the output of rand_list1() :例如rand_list1()的 output :

[[0.07678796 0.22623777 0.07533145]
 [0.07678796 0.22623777 0.07533145]
 [0.07678796 0.22623777 0.07533145]
 [0.07678796 0.22623777 0.07533145]
 [0.07678796 0.22623777 0.07533145]]

and the output of rand_list2() :rand_list2()的 output :

[[0.77863856 0.30345662 0.7007517 ]
 [0.56422447 0.97138115 0.47976387]
 [0.20576279 0.92875791 0.06518335]
 [0.2992384  0.89726684 0.16917078]
 [0.8440534  0.38016789 0.51691172]]
    

There is a basic miscomprehension on how the language works in your question.对于语言在您的问题中的工作方式存在基本的误解。

With the lambda expression, you simply create a new function named l .使用 lambda 表达式,您只需创建一个名为l的新 function。

At the moment you do l() Python will call the function - and it will return a value: it is the returned value that will be used in place of the expression l() in the remaining of the larger expression.此时你执行l() Python 将调用 function - 它会返回一个值:它是将用于代替较大表达式的其余部分中的表达式l()的返回值。 So, in this case, you are actually calling repeat with a single, already generated, number as the first parameter.因此,在这种情况下,您实际上是使用一个已经生成的数字作为第一个参数来调用repeat

FUnctions that are passed as arguments to be called on their destination, and then are run anew each time are an allowed construct in Python, but (1) they depend on the receiving function being able to use functions as arguments, and that is not the case of repeat , and (2) more importanty one has to pass the function name without typing in the parentheses .作为 arguments 传递以在其目的地调用然后每次重新运行的函数是 Python 中允许的构造,但是 (1) 它们依赖于接收 function 能够使用函数作为 arguments,这不是repeat的情况,并且 (2) 更重要的是必须传递 function 名称而不括号中键入。

In this case, repeat is redundant, as the universal syntax that allows one to call a function multiple times to create an iterator already does the repetition you thought repeat would create for you.在这种情况下, repeat是多余的,因为允许多次调用 function 以创建迭代器的通用语法已经执行了您认为repeat会为您创建的重复。

Just do:做就是了:

return [l() for _ in range(5)]

This will call l() for each interaction of the loop.这将为循环的每个交互调用l()

(btw, one should strongly avoid l as a single variable or function name in any context, as in many fonts it ishard to distinguish l from 1 ) (顺便说一句,在任何上下文中都应强烈避免将l作为单个变量或 function 名称,因为在许多 fonts 中很难将l1区分开来)

The reason why list(repeat(l(), 5)) repeats the same value. list(repeat(l(), 5))重复相同值的原因。

itertools.repeat() will just iterate the same result. itertools.repeat()只会迭代相同的结果。

Because l() is assigned the result of l() in list(repeat(l(), 5)) when the l is called (which means l() ).因为 l() 被分配l() in list(repeat(l(), 5))l被调用的结果(这意味着l() )。

itertools.repeat() document itertools.repeat() 文档

repeat(10, 3) --> 10 10 10重复(10, 3) --> 10 10 10

So what is exactly going on?那么到底发生了什么?

stage 1阶段1

 list(repeat(l(), 5))

stage 2第二阶段

 list(repeat([some numbers], 5))

stage 3第三阶段

 list(repeat([some numbers], 5))   --> [some numbers], [some numbers], [some numbers], [some numbers], [some numbers]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM