在最近的一次谈话中,有人分享了一本关于技术工作面试的书中的一些代码。他们想知道我是否同意这些代码是 "Pythonic"。
问题是在一个列表中找到数值增加和减少的运行,并产生一个运行序列,但要把减少的运行倒过来,使它们也是增加的。 这就是 "Pythonic "代码。
import itertools def mono_runs_pythonic(seq): class Monotonic: def __init__(self): self._last = float("-inf") def __call__(self, curr): res = curr < self._last self._last = curr return res return [ list(group)[::-1 if is_decreasing else 1] for is_decreasing, group in itertools.groupby(seq, Monotonic()) ] mono_runs_pythonic([1, 2, 3, 2, 1, 4, 5, 6, 7]) # --> [1, 2, 3], [1, 2], [4, 5, 6, 7]
我的第一个反应是,我不喜欢这段代码,因为我必须用眉毛来读它。 也就是说,我皱着眉头,慢慢地读,在解读代码时皱着眉头。这段代码很密集,很棘手。
它是Pythonic的吗?我想,从它使用了一些Python特有的结构和工具的角度来看,是的。 但从Python代码清晰明了的意义上来说,不是。它彻底地使用了Python,但却忽略了它的精神。
我试着用我自己的解决方案。 它的结果是这样的。
def mono_runs_simpler(seq): seqit = iter(seq) run = [next(seqit)] up = True for v in seqit: good = (v > run[-1]) if up else (v < run[-1]) if good: run.append(v) else: yield run if up else run[::-1] run = [v] up = not up if run: yield run
这段代码也使用了一些不寻常的Python技术,但对我来说更清晰。我不确定每个人都会同意它是更清晰的。也许你有更好的方法来做。
除了哪个代码更好的问题外,我也不喜欢把这段代码作为求职面试的好方案来介绍。 像这样研究代码来学习Python的复杂技巧并不是获得工作的好方法。 或者说,这可能是获得工作的好方法,但我不喜欢它可能会起作用。 工作面试应该关注的是更深层次的问题,而不是你是否知道Python标准库的一些小角落。