我最近申请了一份Python程序员的工作,但被拒绝了。
这就是问题所在:
编写python代码以检查数组是否有序列(1,3,4)
假设他们在寻找专业的Python程序员,我还能做得更好吗?
# Tested with Python 2.7
import unittest
# Runtime: O(n)
def doesSeqAppear(int_arr):
#check if input is a list
if not isinstance(int_arr, list):
raise TypeError("Input shall be of type array.")
# check all elements are of type int
if not all(isinstance(item, int) for item in int_arr) :
raise ValueError("All elements in array shall be of type int.")
arr_len = len(int_arr)
if arr_len < 3:
return False
# Loop through elements
for i in range(arr_len-2):
if int_arr[i] == 1 and \
int_arr[i+1] == 3 and \
int_arr[i+2] == 4 :
return True
return False
class TestMethodDoesSeqAppear(unittest.TestCase):
def test_only_single_seq(self):
#Single time
assert doesSeqAppear([1,3,4]) == True
def test_multiple_seq(self):
#multiple
assert doesSeqAppear([2,2,1,3,4,2,1,3,4]) == True
def test_neg_seq(self):
#multiple
assert doesSeqAppear([9,-1,1,3,4,-4,4]) == True
def test_only_empty_seq(self):
#empty
assert doesSeqAppear([]) == False
def test_only_single_elem_seq(self):
#Single element
assert doesSeqAppear([1]) == False
def test_input_is_none(self):
self.assertRaises(TypeError, doesSeqAppear, None)
def test_raises_type_error(self):
self.assertRaises(TypeError, doesSeqAppear, "string")
def test_raises_value_error(self):
self.assertRaises(ValueError, doesSeqAppear, [1,2,'a', 'b'])
if __name__ == '__main__':
unittest.main()
#发布于 2016-12-14 14:49:24
到PEP 8时,doesSeqAppear应该是does_seq_appear。不过,您在单元测试中使用了正确的命名约定。就我个人而言,我更喜欢def contains_seq(arr, seq=[1, 3, 4])。
您的arr_len < 3测试是多余的,因此应该消除。当常规案例正确和快速地工作时,不要编写特例。
您的all(isinstance(item, int) for item in int_arr)检查没有在问题中指定,因此是有害的。问题不是说doesSeqAppear([3.1, 1, 3, 4])应该返回False,也不是说它应该例外地失败。事实上,根据我的解释,它确实包含了神奇的序列,因此应该返回True。在任何情况下,您都浪费了一个完整的列表迭代,仅仅是为了执行一个没有被要求的检查。
检查isinstance(int_arr, list)是非Pythonic的,因为鸭型是Python的规范。在任何情况下,如果代码不是一个列表,它很可能会自然失败。
在减少了所有这些多余部分之后,您也应该删除# Loop through elements注释。
发布于 2016-12-15 02:20:19
我认为你的回答太长了。这是我的:
def check_for_1_3_4(seq):
return (1, 3, 4) in zip(seq, seq[1:], seq[2:])以下是一些测试:
>>> check_for_1_3_4([1, 3, 4, 5, 6, 7])
True
>>> check_for_1_3_4([5, 6, 7, 1, 3, 4])
True
>>> check_for_1_3_4([5, 6, 1, 3, 4, 7, 8])
True
>>> check_for_1_3_4([1, 3])
False
>>> check_for_1_3_4([])
False
>>> 我的代码看起来很简洁,但是对于任何懂切片和zip的人来说,它仍然是可读的。我希望Python专家至少了解切片技术。
对我来说不幸的是,我的回答不如你的有效。它可以是使用内存的三倍!通过使用生成器,可以创建更高效但更复杂的解决方案。这个新代码没有创建序列的副本,而是只使用原始序列,但逻辑几乎相同。
import itertools
def check_for_1_3_4(seq):
return (1, 3, 4) in itertools.izip(seq,
itertools.islice(seq, 1, None),
itertools.islice(seq, 2, None))测试还没通过。
我不希望大多数Python程序员熟悉itertools,但我的印象是Python专家确实知道这一点。
发布于 2016-12-15 06:42:14
你在这段代码中做了很多假设,或者你在面试中没有提到,或者你错误地假设这个问题是正确的。换句话说,你想的太多了。
#check if input is a list
if not isinstance(int_arr, list):
raise TypeError("Input shall be of type array.")您不应该关心实例类型。该类型很容易是用户定义的类型,它的行为类似于一个列表,甚至是内置的另一个python。例如,python具有deque和array,它们的行为都像一个列表,支持与列表相同的操作。
# check all elements are of type int
if not all(isinstance(item, int) for item in int_arr) :
raise ValueError("All elements in array shall be of type int.")这不一定是正确的,因为一般情况下,python中的列表或集合可以包含许多不同的类型。因此,坚持列表中只包含整数只是强加了一项最初不存在的要求。
最后,我建议您在今后的面试中坚持接吻原则,并在深入研究代码之前提出问题或陈述您的假设。即使这听起来不像是你的假设,也要确保他们知道在你编码的时候或者在你写代码之前你脑子里在想些什么。说“好吧,我也会确定我已经收到了一份清单”听起来可能很傻,但是当他们回答说“别担心,假设这是一份清单”时,你就会省去很多的悲伤。
def check_sequence(arr):
return any((arr[i], arr[i + 1], arr[i + 2]) == (1,3,4) for i in range(len(arr) - 2))https://codereview.stackexchange.com/questions/149867
复制相似问题