我想知道是否有办法重构以下代码
first_run = True
for i in gen:
if first_run:
last_head = i[1]
last_tail = i[2]
last_chrom = i[0]
first_run = False
else:
func(i[1], last_head)
func(i[1], last_tail)
last_head = i[1]
last_tail = i[2]
last_chrom = i[0]
答案 0 :(得分:5)
循环的基本点似乎是对迭代的连续元素对执行某些操作。所以我会查看函数pairwise
,其定义在itertools
module documentation:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
请注意,这不是实际的itertools
函数,您必须将实现复制并粘贴到代码中。无论如何,使用此函数,您的循环可以像这样实现:
for a, b in pairwise(gen):
func(b[1], a[1])
func(b[1], a[2])
答案 1 :(得分:1)
这应该简化循环
first_run = True
for i in gen:
if first_run == False:
func(i[1], last_head)
func(i[1], last_tail)
last_head, last_tail, last_chrom = i[1], i[2], i[0]
first_run = False
更新了答案......
答案 2 :(得分:1)
我会删除 if / else 并通过切片列表分配 - 除非 func 的参数是由它更新的对象: 如果gen是生成器:
my_gen = gen
values = my_gen.next()
last_chrom, last_head, last_tail = values[:3]
for values in my_gen:
func(last_head, last_head)
func(last_head, last_tail)
last_chrom, last_head, last_tail = values[:3]
编辑: 刚注意到我的错误
答案 3 :(得分:0)
如果循环后你不需要变量last_head,last_tail和last_chrom,你可以采用这个解决方案:
for index, val in enumerate(gen[:1]):
func(val[1], gen[index-1][1])
func(val[1], gen[index-1][2])
答案 4 :(得分:0)
it = iter(gen) # make sure we have an iterator
_, last_head, last_tail = next(it, [None]*3) # assume iterator returns 3 values
for _, head, tail in it:
func(head, last_head)
func(head, last_tail)
last_head, last_tail = head, tail
如果你不能假设迭代器一次返回3个值,那么:
it = iter(gen)
last = next(it, None)
for x in it:
func(x[1], last[1]) # head, last_head
func(x[1], last[2]) # head, last_tail
last = x
您还可以使用itertools
' pairwise()
建议的@David食谱:
for last, x in pairwise(gen):
func(x[1], last[1]) # head, last_head
func(x[1], last[2]) # head, last_tail
答案 5 :(得分:0)
我最喜欢以特殊方式处理“第一项”的方法是使用break
的一次性循环:
def gen():
for x in range(5):
yield x
def first_special(g):
for item in g:
print 'first', item
break
for item in g:
print item
first_special(gen())
# prints "first 0, 1,2,3,4
请注意,这适用于单元素或空迭代器。要使first_special
同时使用任意迭代,我通常会向其添加一个安全iter()
调用:
def first_special(g):
g = iter(g)
for item in g:
print 'first', item
break
for item in g:
print item