为什么此代码不能为数字比较提供正确的结果?

时间:2019-03-23 18:03:29

标签: python

我目前正在由Jose Portilla编写Python的Udemy课程。我仍然是一个完整的初学者。练习如下:

“给出一个整数列表,如果数组在某处的3旁边包含3,则返回True。”

has_33([1, 3, 3]) → True
has_33([1, 3, 1, 3]) → False
has_33([3, 1, 3]) → False

我的代码如下。就我的逻辑而言,它应该给我上面的结果,但是它给出了False,False,True,这是完全不可行的:

def has_33(nums):
    for n in nums:
        a = nums.index(n)
        x = nums[a + 1]
        y = nums[a - 1]
        if n == 3 and (x == n or y == n):
            return True
        else:
            return False

4 个答案:

答案 0 :(得分:2)

我尝试解释您的has_33([1, 3, 3])函数的工作方式。这样一来,很明显为什么您的函数没有按预期执行操作。

def has_33(nums):
    # Call function and nums = [1, 3, 3]

    for n in nums:
        # Iterate over nums. n = 1

        a = nums.index(n)
        # Get the index of the list a where element = 1; a = 0

        x = nums[a + 1]
        # 0 + 1 = 1 -> x = nums[1] = 3

        y = nums[a - 1]
        # 0 - 1 = -1 -> y = nums[-1] = 3 (index -1 points to the last element of the list)

        if n == 3 and (x == n or y == n):
            # False, since n != 3 (even though x = 3 and y = 3)

            return True
        else:
            return False
            # When returning, the functin stopts executing, hence n never reaches another element.

答案 1 :(得分:1)

正如评论中指出的那样,这不起作用的主要原因是您在第一次迭代中返回false。关于实现,您可以简化一些事情以更清楚地了解正在发生的事情:

def has_33(nums):
    for a in range(len(nums)-1):
        x = nums[a]
        y = nums[a + 1]
        if x == 3 and y == 3:
            return True
    return False

在您的原始解决方案中,您要按3组进行迭代,在测试将输出以下内容(调用print(y, n, x)之前)添加has_33([1, 2, 3, 3, 4])

item at:   i-1    i    i+1
           ---------------
i = 0       4     1     2
i = 1       1     2     3
i = 2       2     3     3

在第一行4 1 2中,4是位置0-1 = -1处的项目,在python中,负索引对应于位置相对于列表末尾的位置< / strong>。例如,nums[-1]nums中的最后一项,nums[-2]是最后一项之前的某一项,等等。

在第二个代码中,我们仅遍历nums的索引以获取每个x项和以下项y,打印print(x, y)会得出:

item at:    i    i+1
           ---------
i = 0       1     2
i = 1       2     3
i = 2       3     3

请注意,最后我们只是使用索引来获取项目,当索引不用于其他任何事情时,您通常可以使用SetProcessDpiAwarenessContext函数来代替:

def has_33(nums):
    for x, y in zip(nums, nums[1:]):
        if x == 3 and y == x:
            return True
    return False

has_33([1, 2, 3, 3, 1])

这将输出True,并进行记录:

>>> nums
[1, 2, 3, 3, 1]
>>> nums[1:]
[2, 3, 3, 1]
>>> list(zip(nums, nums[1:]))
[(1, 2), (2, 3), (3, 3), (3, 1)]

zip函数将第一个列表中索引为i的项目与第二个列表中索引为i的项目配对。在这里,我们只是从nums中删除了第一项,形成了我们的第二个列表,使用这种策略,我们设法将项i与项i+1配对。

如评论中所述,您甚至可以使用功能zip来完成我们的循环

def has_33(nums):
    return any(p == (3, 3) for p in zip(nums, nums[1:]))

答案 2 :(得分:0)

第3行的代码中存在逻辑错误。您不得使用:

a = nums.index(n)

要获取索引,但您需要使用以下方式:

for a, n in enumerate(nums):

最后有您更正的代码:

def has_33(nums):
    for a, n in enumerate(nums):
        x = nums[a + 1]
        y = nums[a - 1]
        if n == 3 and (x == n or y == n):
            return True
        else:
            return False

为什么? nums.index(n)返回n的第一个位置而不是当前位置。

答案 3 :(得分:0)

所以,您可以尝试一下。

def has_33(numbers):
    str_numbers = ''.join(map(str, numbers))
    return '33' in str_numbers

该函数接受list作为参数,变量str_numbers包含通过map函数和join方法转换为字符串的列表。

例如,如果我的列表是

my_numbers = [1,3,1,3]

变量将其存储为

'1313'

最后但并非最不重要的一点是,返回表达式的求值以查看'33'是否在新创建的变量中,该变量将返回TrueFalse

运行此

my_numbers = [1, 1, 3, 1, 3, 3]


def has_33(numbers):
    str_numbers = ''.join(map(str, numbers))
    return '33' in str_numbers


result = has_33(my_numbers)
print(result)