在PyCharm写Python字典:新手必避7大坑

在PyCharm写Python字典:新手必避7大坑 前言新手写字典列表当键直接报错查无此键程序崩溃边遍历边删当场出错默认值乱用结果变空与is傻傻分不清浅拷贝一改全改自定义键无法查找。七个坑步步惊心。我也曾绊得踉跄、摔得生疼、绕得头晕——直到给键换元组用get()防崩溃删除前先存清单用get()指定默认值拿**判断是不是同一个deepcopy复制彻底给类加哈希功能和相等判断功能。七个招豁然开朗。本文三成速通语法七成排雷避坑——用我的踩坑经验带你避开8大坑字典听你话。如果你不会安装和使用Pycharm和Python.exe请读以下两篇文章。安装Pycharm配置python.exe0基础新手一次成功如何使用PyCharm0基础新手必看七大核心功能越用越有意思字典基础语法速成字典创建与基本结构知识点字典用{}创建核心是键值对键唯一底层用哈希表实现查找极快。实战案例如下新手可以跟着敲。# 通过创建字典创建游戏角色属性卡super_hero{name:剑圣,HP:120,攻击:35}print(super_hero[name])# 输出: 剑圣键值对增删改查知识点查用[]增/改直接赋值删用del。键不存在时查会报错增则新建。实战案例如下新手可以跟着敲。# 3秒修改购物车商品数量cart{梨:3,苹果:2}cart[梨]5# 改cart[香蕉]3# 增delcart[苹果]# 删print(cart[梨])# {梨: 5} #查print(cart)# {梨: 5, 香蕉: 3}字典遍历知识点.keys()取键.values()取值.items()取键值对。遍历是操作字典的核心技能。实战案例如下新手可以跟着敲。# 学生成绩字典姓名是键分数是值scores{小明:85,小红:92}# .keys() 取所有键学生姓名namesscores.keys()print(f学生名单:{list(names)})# .values() 取所有值分数all_scoresscores.values()print(f所有分数:{list(all_scores)})# .items() 取键值对遍历同时拿到姓名和分数forname,scoreinscores.items():# 判断等级90分及以上为A否则为Bifscore90:levelAelse:levelBprint(f{name}:{level})# 输出: 小明:B 小红:A常用内置方法速查知识点.get()安全取值无键返None或默认值.keys()/values()/items()返回视图对象可迭代。实战案例如下新手可以跟着敲。# 内置方法极简演示d{a:1,b:2}print(d.get(c,无))# 安全取: 无print(list(d.keys()))# 所有键: [a, b]print(list(d.values()))# 所有值: [1, 2]print(list(d.items()))# 键值对: [(a, 1), (b, 2)]排雷生存指南坑1可变对象当键问题代码# 列表是可变对象不可哈希用作键会报错name{[1,3]:c}修正代码# 改用不可变的元组当键name{(1,3):c}print(name[(1,3)])# 输出c总结字典键必须是不可哈希不可变类型的如元素。字典键是可哈希可变类型的如列表会报错。坑2键不存在硬取值问题代码user_infomation{001:李四}print(user_infoation[003])# 查询不存在的用户ID修正代码user_infomation{001:李四}# 用get方法优雅处理不存在返回默认值print(user_infomation.get(003,用户不存在))# 输出用户不存在总结直接用[]取值不存在会报错用get()方法可指定默认值来避免崩溃。坑3遍历中删元素问题代码good_orders{001:有效,002:过期,003:过期}fornumberingood_orders:ifgood_orders[number]过期:delgood_orders[number]# 遍历中删除导致字典尺寸变化print(good_orders)修正代码good_orders{001:有效,002:过期,003:过期}# 遍历键的副本避免原字典尺寸变化fornumberinlist(good_orders.keys()):ifgood_orders[number]过期:delgood_orders[number]# 遍历中删除导致字典尺寸变化print(good_orders)总结遍历原字典删除元素时会报错创建字典键的副本会安全地删除元素。坑4默认值的误用问题代码words_count{}words[banana,apple,banana]forwordinwords:# get返回None时1会报错words_count[word]words_count.get(word)1print(words_count)修正代码words_count{}words[banana,apple,banana]forwordinwords:# get指定默认值0避免None参与运算words_count[word]words_count.get(word,0)1print(words_count)# 输出{apple: 2, banana: 1}总结get()默认返回none无法直接参与运算。给get()指定合理默认值如0。坑5与is混淆问题代码dict_1{b:2}dict_2{b:2}# 用is来判断比较上述两字典的内存地址误以为内容相同就相等print(dict_1isdict_2)# 输出False修正代码dict_1{b:2}dict_2{b:2}# 用判断内容是否相等print(dict_1dict_2)# 输出True总结用来比较内容is是用来比较对象内存地址内容相同的字典用**判断为 True用is判断为 False。坑6浅拷贝的陷阱问题代码original_information{user_infomation:{name:李四,age:19}}copy_information_dictoriginal_information.copy()# 浅拷贝仅仅复制表层copy_information_dict[user_infomation][age]25print(original_information[user_infomation][age])# 原件被修改了输出25修正代码importcopy original_information{user_information:{name:李四,age:19}}# 深拷贝是来复制所有层级互不影响deep_copycopy.deepcopy(original_information)deep_copy[user_information][age]22print(original_information[user_information][age])# 输出19总结浅拷贝是仅仅复制表层修改嵌套对象会影响原字典而深拷贝完全独立没有此问题发生。坑7哈希碰撞的坑问题代码classUser:def__init__(self,user_id):self.user_iduser_id# 自定义类实例当键默认哈希基于内存地址导致缓存失效result{User(1):数据1,User(1):数据2}print(len(result))# 输出2本该覆盖只存1个却存了两个修正代码classUser:def__init__(self,user_id):self.user_iduser_iddef__hash__(self):# 实现哈希方法returnhash(self.user_id)def__eq__(self,other):# 进行相等判断returnself.user_idother.user_id result{User(1):数据1,User(1):数据2}print(len(result))# 输出1总结自定义类当键时这需要实现__hash__和__eq__否则因为哈希基于内存地址所以缓存失效。专栏下篇剧透Python新手在PyCharm写while必踩5坑专栏下篇剧透《Python新手在PyCharm写while必踩5坑》。如果你觉得本文有用请动一动你宝贵的手指进行点赞、收藏、关注。我将持续更新PyCharm实战内容Python基础语法痛点突破的干货带你少走弯路。如果你有疑问那就欢迎你在评论区留言。