首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于检查数组是否有序列的Python代码(1,3,4)

用于检查数组是否有序列的Python代码(1,3,4)
EN

Code Review用户
提问于 2016-12-14 13:33:16
回答 4查看 29.4K关注 0票数 9

我最近申请了一份Python程序员的工作,但被拒绝了。

这就是问题所在:

编写python代码以检查数组是否有序列(1,3,4)

假设他们在寻找专业的Python程序员,我还能做得更好吗?

代码语言:javascript
复制
# 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()

#
EN

回答 4

Code Review用户

回答已采纳

发布于 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注释。

票数 10
EN

Code Review用户

发布于 2016-12-15 02:20:19

我认为你的回答太长了。这是我的:

代码语言:javascript
复制
def check_for_1_3_4(seq):
    return (1, 3, 4) in zip(seq, seq[1:], seq[2:])

以下是一些测试:

代码语言:javascript
复制
>>> 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专家至少了解切片技术。

对我来说不幸的是,我的回答不如你的有效。它可以是使用内存的三倍!通过使用生成器,可以创建更高效但更复杂的解决方案。这个新代码没有创建序列的副本,而是只使用原始序列,但逻辑几乎相同。

代码语言:javascript
复制
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专家确实知道这一点。

票数 8
EN

Code Review用户

发布于 2016-12-15 06:42:14

假设

你在这段代码中做了很多假设,或者你在面试中没有提到,或者你错误地假设这个问题是正确的。换句话说,你想的太多了。

代码语言:javascript
复制
#check if input is a list
if not isinstance(int_arr, list):
    raise TypeError("Input shall be of type array.")

您不应该关心实例类型。该类型很容易是用户定义的类型,它的行为类似于一个列表,甚至是内置的另一个python。例如,python具有dequearray,它们的行为都像一个列表,支持与列表相同的操作。

代码语言:javascript
复制
# 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中的列表或集合可以包含许多不同的类型。因此,坚持列表中只包含整数只是强加了一项最初不存在的要求。

最后,我建议您在今后的面试中坚持接吻原则,并在深入研究代码之前提出问题或陈述您的假设。即使这听起来不像是你的假设,也要确保他们知道在你编码的时候或者在你写代码之前你脑子里在想些什么。说“好吧,我也会确定我已经收到了一份清单”听起来可能很傻,但是当他们回答说“别担心,假设这是一份清单”时,你就会省去很多的悲伤。

检查如果数组包含序列(1,3,4)

代码语言:javascript
复制
def check_sequence(arr):
    return any((arr[i], arr[i + 1], arr[i + 2]) == (1,3,4) for i in range(len(arr) - 2))
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/149867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档