请考虑以下代码段:
>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain(*list(bar))
...
>>> list(foo)
[0, 1]
这是有道理的 - 在循环的第一次迭代中,bar
等同于iter([[0]])
,foo的计算结果为chain([0])
,相当于iter([0])
。然后,在循环的第二次迭代中,bar
现在等同于iter([[0, 1]])
,foo变为iter([0, 1])
。这就是list(foo)
为[0, 1]
的原因。
当我使用list(foo)
而不是foo = sum(list(bar), [])
时,我也会得到与chain(*list(bar))
相同的结果。
现在考虑一下这段代码:
>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain.from_iterable(bar)
...
>>> list(foo)
[0, 1, 1, 2]
正如您所看到的,唯一的区别是使用itertools.chain.from_iterable
而不是foo = chain.from_iterable(bar)
的{{1}}行。
在我看来,itertools.chain
大致相当于itertools.chain(*list(iterable))
,但在此情况并非如此。那么为什么最终的结果不同呢?
答案 0 :(得分:5)
不同之处在于chain(*list(bar))
中,条形图立即耗尽,而chain.from_iterable(bar)
中则不是。bar
在i
的定义中,使用i
,它是后期绑定:它在定义时不是i
的值,而是从名称{{1}中获取foo = chain.from_iterable(bar)
的值在它被评估的时候。
IOW,当您使用bar
时,list(foo)
尚未评估。然后,当您拨打bar
时,它会呼叫" i
,定义中的i
会获取名称i
当前引用的值 - 即2。
因此,如果我们手动更改>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain.from_iterable(bar)
...
>>> i = 10
>>> list(foo)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
,我们应该能够适当地更改结果:
def inputnumber() :
x = input('pick a number : ')
if x == 17 :
raise 'BadNumberError' , '17 is a bad number'
return x
答案 1 :(得分:0)
不同之处在于使用生成器和foo = chain.from_iterable(list(bar))
的延迟评估。如果您将此行更改为list(foo)
,这两个程序将是等效的,这会强制条形码生成器的评估以具体值为基础foo。
否则,如上所述,这两个程序在语义上是不同的,因为前者将链应用于列表,而第二个程序将链应用于生成器,在某些方面可以将其视为函数句柄,这将执行推迟到最终循环结束后调用 import processing.core.*;
import java.awt.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
public class MinimTest2 extends PApplet {
Minim minim;
FFT fft;
AudioInput in;
float[] amp = new float[430];
float[] temp;
public void settings() {
size(800, 600);
}
public MinimTest2()
{
minim = new Minim(this);
in = minim.getLineIn();
fft = new FFT(in.bufferSize(), in.sampleRate());
}
public float[] getAmps(){
fft.forward(in.left);
amp = new float[430];
temp = new float[fft.specSize()];
int index = 0;
for (int k=0; k<fft.specSize(); k++){
temp[index]=fft.getBand(k);
index++;
}
for (int i=0; i<amp.length; i++)
amp[i]=temp[i];
return amp;
}
public int getFFTSize(){
return fft.specSize();
}
}
。
[这个答案在Python 3中测试过,其中range是一个生成器。它可能在Python 2.x中表现不同,其中range返回整个列表...]