如何用更Pythonic的方式断言数组全为负数或全为非负数?
嘿,你的思路已经很到位了,第二段代码通过一次生成判断结果列表再复用,确实比第一段少了一次遍历,效率更优。这里给你几个更Pythonic、更高效的写法和思路参考:
1. 一次遍历提前终止(效率天花板)
如果数组很大,或者希望尽早返回结果,这种写法最优——遍历过程中只要发现同时存在负数和非负数,直接返回False,不用走完整个数组:
def check(arr): has_negative = False has_non_negative = False for num in arr: if num < 0: has_negative = True else: has_non_negative = True # 一旦两种数都出现,直接终止判断 if has_negative and has_non_negative: return False return True
2. 更简洁的复用判断结果(类似你的第二段但更省内存)
你的第二段用列表存储判断结果是对的(因为列表可以重复遍历),但其实可以用itertools.tee把生成器拆成两个可迭代对象,避免创建列表占用内存:
from itertools import tee def check(arr): negatives, negatives_copy = tee(num < 0 for num in arr) return all(negatives) or not any(negatives_copy)
不过要注意,tee的开销在小数组上可能比直接用列表大,适合处理大数组时平衡内存和效率。
3. 可读性拉满的一行写法(小数组友好)
如果数组规模不大,这种写法足够简洁直观,Pythonic十足:
def check(arr): return all(x < 0 for x in arr) or all(x >= 0 for x in arr)
虽然是两次遍历,但Python的循环开销很小,小数组下几乎感受不到差异,胜在代码清晰易懂。
4. 反向逻辑的巧妙写法
换个思路:只要数组不同时存在负数和非负数,就符合要求。这种逻辑的可读性也不错:
def check(arr): has_neg = any(x < 0 for x in arr) has_non_neg = any(x >= 0 for x in arr) return not (has_neg and has_non_neg)
另外要提醒你:如果想用生成器代替列表(比如你的第二段改成生成器),要注意生成器只能遍历一次,会导致后续的any/all拿到空迭代器,出现错误结果——你的第二段用列表是完全正确的选择!
内容的提问来源于stack exchange,提问作者goodvibration
相关产品推荐
相关产品推荐

