【采坑】python字典初始化
在做图像识别的课题时,我遇到了一个问题,需要按照使用slic算法计算后输出的数组对于某一张图片进行切分,因此需要使用一个字典来记录每个色块对应的范围。
字典对应的形式如下,其中key对应的是slic算法输出的每一个颜色块的index
,value代表了[most_top, most_bottom, most_left, most_right]
1 | {1:[1, 5, 3, 4]} |
分别记录了每个颜色块的上下左右边界,需要按照下述方式进行初始化。
1 | most_top = image_height # 最上边界:设置为最下面 |
因此对于字典也需要初始化,每个字典的keys值分别对应slic输出的数组中每一个index
值,value为按照上述方式进行初始化的结果。
为了实现这个,我google到了这篇文章:python 字典初始化方法 全!!!
在这篇文章中我发现了一个最适合当前场景的方法,便是使用dict.fromkeys
方法,于是照猫画虎,我对于自己这个需求写出了如下代码
1 | len_color = len(Counter(segments.reshape(-1))) # 统计数组中的类别个数 |
这里的segments为使用slic算法输出的结果。
看似上面的代码完美无缺对不对(这只抹茶好不要脸哦!)
然后在运行的时候我遇到了一个问题,那便是图像并没有按照预想的按照每一个颜色块的大小进行分割,而是输出了每张图的原图。
在认真检查过代码的逻辑之后,我觉得我可以99%地保证自己的代码逻辑没有任何问题。因为我实在是无法检查出来任何问题了。
于是这个时候只有祭出那个大法了,也就是IDE的Debug功能,虽然是第一次使用pycharm的debug功能,不过有着vs的debug经验,具体方法是大同小异的,所以也很快就进入状态了。
在debug的时候,经过我反复的操作,我突然发现1号色块的对应字典的value中即使是已经超出边界行,其value中的边界值仍然处于增加状态,这个时候我就非常的好奇,最初认为自己是哪里没有看到,于是就调出了segments来看,结果发现我自己并没有判断错误,在我反复的使用print大法来断定之后我仍然没有找到任何一点问题。
索性放弃,吃过晚饭后,我突然想起来看一下编译器下面debug时候一个没有在意的地方,也就是那个字典。将字典展开之后,我突然发现一件事情,字典中的所有value每一个里面的list的值都是相同的,最初因为色块相邻,所以没有在意这个问题。
当我再仔细看的时候,发现每一个value上面都标着了一个list4,最初我认为这个4代表的是每一个list中有四个元素,后来看了其他地方的标志我才意识到这个list的标志并非代表的4个元素,而是系统自动为每一个变量标记的名称,也就是说,这一个字典中的所有value中的list在底层都是同一个list的引用,大概用c语言的话来说,就是我用字典存储了若干份这个list的指针,然后无论哪一个色块进行改变的时候都会改变这唯一一个list,所以在后期循环字典切割图片的时候,每一个对应色块其实访问的都是一整张图片所对应的范围,所以每张图片才会输出成为原图的样子。
于是在反复经过试验之后,我尝试了下述代码
1、list转换法
1 | color_dic = dict.fromkeys([x for x in range(1, len_color + 1)], list([most_top, most_bottom, most_left, most_right])) |
2、元组法
1 | color_dic = dict.fromkeys([x for x in range(1, len_color + 1)], (most_top, most_bottom, most_left, most_right)) |
3、元组+list转换法
1 | color_dic = dict.fromkeys([x for x in range(1, len_color + 1)], list((most_top, most_bottom, most_left, most_right))) |
结果在实验的时候发现,无论哪一个都以失败告终,这下我终于明白了究竟是哪里的问题。
这样写的话,字典中每一个value对应的都是第二个参数中的这个值,每个都是一个引用。应该摒弃
掉这个方法,使用普通的循环就可以解决的!
也就是下面这段代码
1 | for x in range(1, len_color + 1): |
这样的话,每个key对应的value都是一个新的list,就不会再出现这种问题了。
case closed!(没事学什么福尔摩斯啊,掟上今日子看多了啊喂!)
在服务器中住着的AKI娘会检测您的输入内容哦, 如果被判断为垃圾内容是看不到的呢!当然抹茶也会定期检查AKI娘的所作所为的!