如何在Python中使用可能未分配的目标迭代器?

时间:2016-06-24 15:11:32

标签: python iterator

如果想在任意可互换数据源上运行算法,最好使用迭代器:

def do_something(iter):
    for x in iter:
        print(x)

l = list([1, 2, 3])
do_something(iter(l))

在给定的示例中,迭代器是。但是,如果我想将迭代器用作目标,它会怎样?类似的东西:

def do_something(iter, target):
    for x in iter:
        # if x is prime, insert it into target

l = list([1, 2, 3])
primes = ... # something that will be able to take the primes
do_something(iter(l), primes)

我可以使用list的{​​{1}},但如果目标迭代器不是列表,而是一些不同的迭代器,那么这将不起作用。

在该示例中,甚至没有分配目标迭代器。我也想知道我如何/应该预先分配以及使用append和NumPy看起来如何。

2 个答案:

答案 0 :(得分:2)

首先,只是一个术语说明:迭代器是一个只读构造;它是一个具有next方法的对象。所以target不是迭代器,而是其他东西。

你想要的是保证有append方法的东西,它是从collections.MutableSequence继承的任何类。 list只是一个这样的类,虽然(唯一的?)是标准库的一部分。

Python是动态类型语言,它不是必需 target是继承自MutableSequence的类型的实例。这是足够的条件(这样的对象可以工作),但它不是必要的条件(对象可以有一个合适的append方法而不实际继承来自MutableSequence)。

所以简短的回答是:继续使用append。请确保文档 target参数必须支持append,并让您的用户决定使用哪些内容。

答案 1 :(得分:1)

一种选择是使用生成器并使用.send方法将值返回到yield语句:

def is_prime(n): #for this demo
    return not any(n%i==0 for i in range(2,n))

def do_something(iter, target):
    for x in iter:
        if is_prime(x):
            target.send(x)

def show_results(message):
    while True:
        x = yield
        print(message, x)

l = range(10)
primes = show_results("this is a prime number:")
next(primes) #need to do this before sending values to a generator
do_something(iter(l), primes)

虽然你也可以只传递一个callable作为目标,但是你可以将generator.sendlist.append作为target传递,或者通过单一传递任何其他函数值:

def do_something(iter, process_func):
    for x in iter:
        if is_prime(x):
            process_func(x)

l = range(10)
primes = show_results("this is a prime number:")
next(primes) #need to do this before sending values to a generator
do_something(iter(l), primes.send)

#or

primes = []
do_something(iter(l), primes.append)
print(primes)