我最近开始学习Python和for循环的概念对我来说还是有点混乱。 我明白,这一般遵循格式for x in y
,其中y
只是一些名单。
的for-each循环for (int n: someArray)
成为for n in someArray
,
和for循环for (i = 0; i < 9; i-=2)
可以由下式表示for i in range(0, 9, -2)
假设,而不是一个恒定的增量,我想i*=2
,甚至i*=i
。 这是可能的,否则我将不得不使用while循环呢?
正如你所说,一个for
在列表中的元素循环迭代。 该列表可以包含任何你喜欢的,这样你就可以提前构建一个列表,其中包含每一个步骤。
甲for
循环也可以遍历一个“发电机” ,这是一小块代码而不是实际的列表。 在Python, range()
实际上是一台发电机(在Python 2.x中,虽然, range()
返回一个列表,而xrange()
是生成器)。
例如:
def doubler(x):
while True:
yield x
x *= 2
for i in doubler(1):
print i
以上for
循环将打印
1
2
4
8
并依此类推,直到你按下Ctrl + C。
您可以使用生成器表达式有效,几乎没有多余的代码做到这一点:
for i in (2**x for x in range(10)): #In Python 2.x, use `xrange()`.
...
生成器表达式的工作就像定义手动发电机(如格雷格Hewgill的回答 ),用类似于列表中理解语法。 他们懒洋洋地评估 - 这意味着他们没有在操作,这可能会导致大iterables更好的性能开始生成一个列表。
所以这个发电机的工作原理是等待,直到它被询问的值,然后要求range(10)
中的数值,倍增该值,并将其传递回for
循环。 为此,它会反复,直到range()
发生器所产生的没有更多的价值。
请记住,Python的的“列表”部分可以是可迭代的序列。
例子:
的字符串:
for c in 'abcdefg':
# deal with the string on a character by character basis...
一份文件:
with open('somefile','r') as f:
for line in f:
# deal with the file line by line
一本字典:
d={1:'one',2:'two',3:'three'}
for key, value in d.items():
# deal with the key:value pairs from a dict
一个列表的片段:
l=range(100)
for e in l[10:20:2]:
# ever other element between 10 and 20 in l
等等等等,等等等等。
所以这真的是比“只是一些列表”更深了很多
正如其他人所指出的,刚才设置的迭代是你希望它是你的问题示例内容:
for e in (i*i for i in range(10)):
# the squares of the sequence 0-9...
l=[1,5,10,15]
for i in (i*2 for i in l):
# the list l as a sequence * 2...
您将要使用列表理解这个
print [x**2 for x in xrange(10)] # X to the 2nd power.
和
print [x**x for x in xrange(10)] # X to the Xth power.
该列表中理解语法是一个如下所示:
[EXPRESSION for VARIABLE in ITERABLE if CONDITION]
引擎盖下,它的作用类似于图和滤波器功能 :
def f(VARIABLE): return EXPRESSION
def c(VARIABLE): return CONDITION
filter(c, map(f, ITERABLE))
实施例给出:
def square(x): return x**2
print map(square, xrange(10))
和
def hypercube(x): return x**x
print map(hypercube, xrange(10))
这可以作为替代的方法,如果你不喜欢列表理解。 你还可使用for循环,而是会被Python的惯用一步之遥......
只是一种替代,如何推广的迭代/增量操作lambda函数,所以你可以做这样的事情:
for i in seq(1, 9, lambda x: x*2):
print i
...
1
2
4
8
当seq
被定义如下:
#!/bin/python
from timeit import timeit
def seq(a, b, f):
x = a;
while x < b:
yield x
x = f(x)
def testSeq():
l = tuple(seq(1, 100000000, lambda x: x*2))
#print l
def testGen():
l = tuple((2**x for x in range(27)))
#print l
testSeq();
testGen();
print "seq", timeit('testSeq()', 'from __main__ import testSeq', number = 1000000)
print "gen", timeit('testGen()', 'from __main__ import testGen', number = 1000000)
在性能上的差异不算多:
seq 7.98655080795
gen 6.19856786728
[编辑]
为了支持反向迭代,并用默认参数...
def seq(a, b, f = None):
x = a;
if b > a:
if f == None:
f = lambda x: x+1
while x < b:
yield x
x = f(x)
else:
if f == None:
f = lambda x: x-1
while x > b:
yield x
x = f(x)
for i in seq(8, 0, lambda x: x/2):
print i
注意:此行为不同,以range
/ xrange
中的方向<
/ >
试验是通过迭代器标志,而不是开始和结束值之间的差选择。