我最近开始学习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循环吗?
答案 0 :(得分:11)
正如您所说,for
循环遍历列表的元素。该列表可以包含您喜欢的任何内容,因此您可以预先构建包含每个步骤的列表。
for
循环也可以迭代"generator",这是一小段代码而不是实际列表。在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.
答案 1 :(得分:8)
您可以使用generator expression来有效地执行此操作,而且代码过多:
for i in (2**x for x in range(10)): #In Python 2.x, use `xrange()`.
...
生成器表达式的工作方式与定义手动生成器(如Greg Hewgill's answer)一样,其语法类似于列表推导。它们被懒惰地评估 - 意味着它们不会在操作开始时生成列表,这可以在大型迭代上产生更好的性能。
所以这个生成器的工作方式是等待它被要求输入一个值,然后向range(10)
询问一个值,将该值加倍,然后将其传递回for
循环。它会反复执行此操作,直到range()
生成器不再生成值。
答案 2 :(得分:5)
请记住,Python的'list'部分可以是任何可迭代的序列。
示例:
字符串:
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...
答案 3 :(得分:1)
您需要list comprehensions用于此
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]
在幕后,它的行为类似于map and filter function:
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惯用...
答案 4 :(得分:0)
只是为了替代,如何将迭代/增量操作推广到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
的行为方式不同,其中方向<
/ >
测试由迭代器符号选择,而不是开始和结束价值。