美文网首页python热爱者Python新世界
今天长见识了,有人说python有个BUG,我去试了下居然是真的

今天长见识了,有人说python有个BUG,我去试了下居然是真的

作者: 48e0a32026ae | 来源:发表于2018-11-22 19:27 被阅读4次

今天在像以前一样 做题的时候,遇到一个迷一样的 BUG ,仔细一想才想起来这是Python的一个特性,以前也遇到过,没想到今天又遇到了。话不多说,先来看题:

学习Python中有不明白推荐加入交流群

                号:516107834

                群里有志同道合的小伙伴,互帮互助,

                群里有不错的学习教程!

题目要求

问题描述

在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色。

下图给出了一个画了两个矩形的例子。第一个矩形是(1,1) 到(4, 4),用绿色和紫色表示。第二个矩形是(2, 3)到(6, 5),用蓝色和紫色表示。图中,一共有15个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。在实际的涂色过程中,所有的矩形都涂成统一的颜色,图中显示不同颜色仅为说明方便。

给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式

输入的第一行包含一个整数n,表示要画的矩形的个数。

接下来n行,每行4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式

输出一个整数,表示有多少个单位的面积被涂上颜色。

样例输入

2

1 1 4 4

2 3 6 5

样例输出

15

评测用例规模与约定

1<=n<=100,0<=横坐标、纵坐标<=100。

当时我的答案是这样的:

n = int(input())

# 生成一个坐标系块,默认全为 0

panel = [[0]*100]*100

# 色块数量

cnt = 0

for i in range(n):

read = [int(x) for x in input().split()]

for x in range(read[0], read[2]):

for y in range(read[1], read[3]):

if panel[x][y] == 0:

panel[x][y] = 1

cnt += 1

print(cnt)

却发现结果不太对,输入示例数据,结果只有 4 ?剩下的 11 个是被吃了吗?仔细看逻辑也没问题啊,这时候突然想到 Python 的一个特性,赶紧写个测试代码试一下:

a = [[0]*3]*3

print(a)

a[0][0] = 1

print(a)

结果如下:

[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

我们发现,明明只是置 [0][0] 为 1 ,怎么所有的第二维数组的 [0] 全为 1 了呢?你遇到过这种情况吗?

原来这是因为 Python 相同的值只存一份的特性决定的。不管有多少个 [0,0,0] 对于 Python 来说,内存中只存一份,所有的 [0,0,0] 都是这块内存的引用,所以在对二维数组的 [0][0] 进行赋值的时候,内存中的值被改变,所有 [0,0,0] 的引用也被改变!正是这个原因,所有答案输出的结果才与我们预期的不一样。要想正确输出只需将代码稍微改一下即可:

n = int(input())

panel = [0]*10000

cnt = 0

for i in range(n):

read = [int(x) for x in input().split()]

for x in range(read[0], read[2]):

for y in range(read[1], read[3]):

if panel[x*100+y] == 0:

panel[x*100+y] = 1

cnt += 1

print(cnt)

其实对于 Python 来说,不光是相同的列表只存一份,元组、集合、字典也是只存一份,所以一个相同的数据赋值给多个变量时,如果进行修改操作时要小心了,一不小心就把所有的地方都改了。

另外对于 ‘a' , 1 等常量也遵循只存一份的原则。

a = 1

b = 1

对于以上代码,将 1 赋值给 a ,再将 1 赋值给 b 。在这里 a 代表的 1 和 b 代表的 1 其实是同一个 1 ,引用的是同一个地址。也就是说,在 Python 中,没有真正的值传递,所有的数据都是引用类型的。只不过指向常量等不可变类型的变量在改变时会换一个内存地址,若是列表这种可变类型,在修改时就会直接修改内存中的值,因此所有的引用都会被改变。你明白了吗?

相关文章

  • 今天长见识了,有人说python有个BUG,我去试了下居然是真的

    今天在像以前一样 做题的时候,遇到一个迷一样的 BUG ,仔细一想才想起来这是Python的一个特性,以前也遇到过...

  • 2020-04-20

    今天尝试了一下最新的国产操作系统 deepin v20用了一下,有很多bug, 优点:预装了python 3.7 ...

  • 我不配

    今天去微博瞧了一下,妈妈呀,惊呆我了,真的有天才,可惜不是我,嘤嘤嘤 看到有个热搜,14岁的男娃娃,居然是985/...

  • 今天我去面试了

    文||南卿言 今天下午,我去面试了,跟公司里的HR聊了近两个小时,从为什么回来面试,到想要的工作,到职业规划,再到...

  • 今天我去面试了

    天气从昨天开始变得异常的冷。记忆中好像一些重要的日子总是那么的阴冷。或许是预见了事情的结局不会太好了。今天去参加了...

  • 今天我去面试了

    今天,我一共去参加了两场面试,上午一场,下午一场。 都说每年年后的“金三银四”是跳槽季,可是我觉得这种说法似乎有些...

  • 我今天去面试了

    今天终于有机会去面试了!!!之前投的简历大都石沉大海。 新的面试跟现在的工作内容差不多都是证券类型的工作。面试时间...

  • javaScript 小数计算精度丢失

    情景举例 : 有天对象问我一个问题,说前端计算有Bug,根据她的描述我抱着怀疑的态度去控制台试了试,写了一个22...

  • 今天去面试了

    今天的天气很好,晴空万里,很适合出门面试。 我今天面试的岗位又是和本专业毫不相关的工作,是老家一所私立中学的初中语...

  • 今天去面试了

    今天下午我去了我面试的工作地点, 开始一进去感觉人还挺多的,挺正规的,后面填写了资料后,就去经理那面试去了,经理问...

网友评论

    本文标题:今天长见识了,有人说python有个BUG,我去试了下居然是真的

    本文链接:https://www.haomeiwen.com/subject/rdrrqqtx.html