Python 数据容器详解,list、tuple、str、set、dict 到底怎么选
变量能保存一个值。但程序真正开始有用往往是从处理一批数据开始的。学生名单、商品列表、电影信息、订单记录、接口返回的 JSON这些都不是一个变量能优雅解决的。Python 提供了几种非常常用的数据容器list、tuple、str、set、dict很多初学者的问题不是不会写语法而是不知道什么时候该用谁。这篇文章就把它们一次讲清楚。先看一个真实一点的数据结构假设我们要表示一部电影movie{title:流浪地球,year:2019,score:7.9,tags:[科幻,冒险,灾难],directors:(郭帆,)}print(movie[title])print(movie[tags][0])这里同时用了字典、列表和元组。字典描述一部电影的多个属性。列表保存多个标签。元组保存不太需要修改的导演信息。真实项目里的数据经常就是这样嵌套的。list最常用的列表列表有顺序可以修改适合保存一组同类数据。students[小明,小红,小刚]print(students[0])print(students[1])索引从 0 开始。常用操作students[小明,小红]students.append(小刚)students.insert(1,小李)students.remove(小红)print(students)print(len(students))append()加到末尾。insert()插入指定位置。remove()按值删除。len()获取长度。列表切片切片格式items[start:end:step]示例numbers[10,20,30,40,50]print(numbers[1:4])print(numbers[:3])print(numbers[2:])print(numbers[::2])输出[20, 30, 40] [10, 20, 30] [30, 40, 50] [10, 30, 50]规则是包含开始位置不包含结束位置。这个规则刚开始有点别扭但非常统一。range()也是不包含结束值。列表遍历只需要元素scores[90,85,72]forscoreinscores:print(score)同时需要索引和元素scores[90,85,72]forindex,scoreinenumerate(scores):print(index,score)不要为了拿索引强行写scores[90,85,72]forindexinrange(len(scores)):print(scores[index])这不是错但如果你不需要索引直接遍历元素更清楚。tuple固定结构的数据元组有顺序但创建后不能修改。point(120.1,30.2)print(point[0])print(point[1])元组适合保存结构固定的数据比如坐标、日期片段、函数多个返回值。defget_min_max(numbers):returnmin(numbers),max(numbers)min_value,max_valueget_min_max([3,8,1,9])print(min_value)print(max_value)这里函数返回了两个值。Python 实际上返回的是一个元组只是我们可以很方便地拆开。str字符串也是序列字符串是文本也是一种不可变序列。wordPythonprint(word[0])print(word[1:4])字符串常用方法text Python,AI,Web print(text.strip())print(text.lower())print(text.replace(AI,Data))print(text.split(,))strip()去掉两端空白。lower()转小写。replace()替换文本。split()按分隔符切分成列表。字符串不能直接修改某个字符wordPython# word[0] J 这行会报错要生成新字符串wordPythonnew_wordJword[1:]print(new_word)set去重和集合运算集合不保存重复元素。tags{Python,AI,Python,Web}print(tags)集合适合做去重names[小明,小红,小明,小刚]unique_namesset(names)print(unique_names)集合运算frontend{HTML,CSS,JavaScript,Python}backend{Python,Java,Go}print(frontendbackend)print(frontend|backend)print(frontend-backend)是交集。|是并集。-是差集。集合不适合用索引因为它不强调顺序。dict用键找到值字典保存键值对。user{name:小明,age:18,is_vip:True}print(user[name])修改和新增user{name:小明,age:18}user[age]19user[city]杭州print(user)安全读取user{name:小明}print(user.get(age,未知))如果直接user[age]键不存在会报KeyError。get()可以给默认值。字典遍历遍历键user{name:小明,age:18}forkeyinuser:print(key)遍历值forvalueinuser.values():print(value)遍历键和值forkey,valueinuser.items():print(key,value)真实开发里items()很常用。容器怎么选可以按这个流程判断是否是是否否是否要组织数据是否描述一个对象的多个属性dict是否保存一组有顺序的数据是否需要修改listtuple是否主要为了去重或集合运算set重新检查数据模型简单判断保存多个学生用列表。描述一个学生用字典。保存坐标用元组。处理标签去重用集合。处理文本用字符串。可变和不可变列表、字典、集合是可变的。字符串、元组、数字是不可变的。看列表items[1,2,3]items.append(4)print(items)原列表被修改了。看字符串namePythonnew_namename.replace(P,J)print(name)print(new_name)原字符串没有变生成了新字符串。这个区别会影响函数参数、复制、数据共享。现在先记住规则后面写项目时会经常遇到。浅拷贝的入门坑numbers[1,2,3]other_numbersnumbers other_numbers.append(4)print(numbers)输出[1, 2, 3, 4]因为numbers和other_numbers指向同一个列表。如果想复制一份numbers[1,2,3]other_numbersnumbers.copy()other_numbers.append(4)print(numbers)print(other_numbers)这只是浅拷贝。嵌套结构会更复杂入门阶段先知道不要随便把可变对象赋来赋去。完整案例学生成绩统计students[{name:小明,score:90,tags:{认真,稳定}},{name:小红,score:85,tags:{活跃,进步}},{name:小刚,score:72,tags:{稳定}},]total_score0passed_students[]all_tagsset()forstudentinstudents:total_scoretotal_scorestudent[score]ifstudent[score]60:passed_students.append(student[name])all_tagsall_tags|student[tags]average_scoretotal_score/len(students)print(f平均分{average_score:.2f})print(f及格学生{passed_students})print(f所有标签{all_tags})这个例子里列表保存多个学生。字典描述单个学生。集合保存标签并自动去重。循环负责逐个处理。这就是容器组合的真实用法。常见错误索引越界names[小明,小红]print(names[2])列表只有索引 0 和 1访问 2 会报IndexError。字典键不存在user{name:小明}print(user[age])会报KeyError。修复print(user.get(age,未知))修改正在遍历的列表numbers[1,2,3,4]fornumberinnumbers:ifnumber%20:numbers.remove(number)这类代码容易跳过元素。更安全的方式是生成新列表numbers[1,2,3,4]odd_numbers[]fornumberinnumbers:ifnumber%2!0:odd_numbers.append(number)print(odd_numbers)练习写一个图书统计程序用列表保存多本书。每本书用字典表示包含书名、价格、标签。统计所有书的平均价格。汇总所有标签并去重。参考代码books[{title:Python 入门,price:59.9,tags:{编程,Python}},{title:数据分析基础,price:69.0,tags:{数据,Python}},{title:Web 开发,price:79.0,tags:{Web,Python}},]total_price0all_tagsset()forbookinbooks:total_pricetotal_pricebook[price]all_tagsall_tags|book[tags]average_pricetotal_price/len(books)print(f平均价格{average_price:.2f})print(f全部标签{all_tags})参考资料Python 官方数据结构教程https://docs.python.org/3/tutorial/datastructures.html

相关新闻