繁体   English   中英

如何对迭代器进行操作,然后对python中的下一个迭代器进行其他操作

[英]How to do something to an iterator, then something else to the next iterator in python

对列表中的第一个元素执行某种操作,对第二个元素进行其他操作,对列表中的第三个元素进行其他操作的“正确” python方法是什么,然后重复执行,例如:

a = [2, "foo1", "bar1", 5, "foo3", "bar2", 3, "foo2", "bar3"]
my_function(a)

应该给

20
foo1
foobar1
50
foo3
foobar2
30
foo2
foobar3

其中“ my_function”类似于:

def my_function(a):
    i = 0
    for line in a:
        if i == 0:
            line = line*10
        if i == 2:
            line = "foo"+line
        i = i + 1
        if i == 3:
            i = 0
        print line

但这看起来非常“ unpython”。 是否有这样做,没有更好的办法int跟踪? 可以这样说,我第一次调用此函数,但是第二次调用此函数,然后第三次调用此函数,然后回到开始并首先执行操作。 跟踪已调用次数的函数。

使用迭代器,您可以执行以下操作:

def my_function(a):
    a = iter(a)
    while True:
        yield 10 * next(a)    
        yield next(a)
        yield "foo" + next(a)

a = [2, "foo1", "bar1", 5, "foo3", "bar2", 3, "foo2", "bar3"]    
print list(my_function(a))
#prints [20, 'foo1', 'foobar1', 50, 'foo3', 'foobar2', 30, 'foo2', 'foobar3'] 

如果有人想知道列表末尾会发生什么, next(a)将引发StopIteration 异常终止生成器my_function ,但是对其进行迭代的代码(在本例中为list()会将其识别为正常的迭代结束。

我可能会做类似的事情:

def my_function(lst):
    items = (lst[i:i+3] for i in xrange(0, len(lst), 3))
    for group in items:
       yield group[0] * 10
       yield group[1]
       yield 'foo' + group[2]

在您的输入上运行:

>>> list(my_function(a))
[20, 'foo1', 'foobar1', 50, 'foo3', 'foobar2', 30, 'foo2', 'foobar3']

我在这里做了两个大假设-您的列表确实是一个列表(或至少一个序列),并且序列的长度可以被3整除(否则,您将得到IndexError )。 无需过多的努力就可以解决这两个假设,但是如果您真的有兴趣,我将其保留为练习;-)

您可以使用类似:

def my_function (a):
    actions = [lambda l: l * 10,
               lambda l: l,
               lambda l: "foo" + l]
    for i, line in enumerate(a):
        line = actions[i % 3](line)
        print line

使用zipiter组合的现有选项的其他选项( 在此处进行说明 ):

def my_function2(a):
    for v1,v2,v3 in zip(*[iter(a)]*3):
        print(v1*10,v2, 'foo'+ v3)

% gives
20 foo1 foobar1
50 foo3 foobar2
30 foo2 foobar3

为此使用itertools ,我发现它对元素/动作的数量最为优雅和有弹性:

import itertools


def my_function(a):
    actions = itertools.cycle(
        (lambda l: l * 10, lambda l: l, lambda l: "foo" + l)
    )

    for val, action in itertools.izip(a, actions):
        yield action(val)

a = [2, "foo1", "bar1", 5, "foo3", "bar2", 3, "foo2", "bar3", 7]
print list(my_function(a))

结果:

[20, 'foo1', 'foobar1', 50, 'foo3', 'foobar2', 30, 'foo2', 'foobar3', 70]

从示例中可以看到,即使元素计数不是操作计数的乘积(甚至小于操作计数)也可以使用。

这是python2版本,如果需要3,请指定。

假设a列表作为输入的功能,

def my_function(a):
   a[::3] = map(lambda x: 10*x, a[::3])
   a[2::3] = map(lambda x: "foo"+x, a[2::3])

在这里,我正在使用python中的扩展片 我认为这更多是一种Python方式。

这是类似于C方式,而不是Pythonic 因此,如果您了解C ,那么只需几秒钟即可了解它。

def my_function(a):
    for n, line in enumerate(a):
        if n % 3 == 0:
            line = line * 10
        elif n % 3 == 2:
            line = "foo" + line
        print line

暂无
暂无

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

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