如果想在任意可互换数据源上运行算法,最好使用迭代器:
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看起来如何。
答案 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.send
或list.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)