max*_*max 5 python iterator filter python-3.x
(在Python 3.1中)(与我提出的另一个问题有些相关,但这个问题是关于迭代器已经用尽了.)
# trying to see the ratio of the max and min element in a container c
filtered = filter(lambda x : x is not None and x != 0, c)
ratio = max(filtered) / min(filtered)
Run Code Online (Sandbox Code Playgroud)
我花了半个小时才意识到问题是什么(过滤器返回的迭代器在到达第二个函数调用时已经耗尽).如何以最Pythonic /规范的方式重写它?
另外,除了获得更多经验之外,我还能做些什么来避免这种错误呢?(坦率地说,我不喜欢这种语言功能,因为这些类型的错误很容易制作,很难捕捉到.)
该itertools.tee功能可以在这里帮助:
import itertools
f1, f2 = itertools.tee(filtered, 2)
ratio = max(f1) / min(f2)
Run Code Online (Sandbox Code Playgroud)
你可以简单地通过调用元组(迭代器)将迭代器转换为元组
但是我会将该过滤器重写为列表理解,这看起来像这样
# original
filtered = filter(lambda x : x is not None and x != 0, c)
# list comp
filtered = [x for x in c if x is not None and x != 0]
Run Code Online (Sandbox Code Playgroud)
实际上你的代码引发了一个异常,可以防止这个问题!所以我猜问题是你掩盖了异常?
>>> min([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence
>>> min(x for x in ())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence
Run Code Online (Sandbox Code Playgroud)
无论如何,您还可以编写一个新功能,同时为您提供最小值和最大值:
def minmax( seq ):
" returns the `(min, max)` of sequence `seq`"
it = iter(seq)
try:
min = max = next(it)
except StopIteration:
raise ValueError('arg is an empty sequence')
for item in it:
if item < min:
min = item
elif item > max:
max = item
return min, max
Run Code Online (Sandbox Code Playgroud)