聊起Python怎么归并数据,这事儿吧,真有点像整理房间。有时候,你只需要把两堆书简单摞在一起;有时候,你得精心地按作者、按颜色、按大小重新排列组合,甚至还得扔掉几本重复的。Python里的归并,就是这么个理儿,从简单粗暴到精雕细琢,门道多着呢。
列表(List)的归并:简单直接的暴力美学
先说最常见的列表。咱们手里有俩列表,list_a 和 list_b,想把它们揉成一个。
最直观,最不过脑子的方法,就是直接用 + 号。
“`python
list_a = [1, 2, ‘猫’]
list_b = [‘狗’, 4, 5]
new_list = list_a + list_b
new_list 就成了 [1, 2, ‘猫’, ‘狗’, 4, 5]
“`
看到了吧?简单、粗暴、有效。就像把两筐土豆直接倒进一个大麻袋,不分你我。这种方式的特点是,它会创建一个全新的列表 new_list,原来的 list_a 和 list_b 屁事没有,安然无恙。在大多数情况下,这招就够用了,而且代码清爽,一眼就能看懂。
但是,如果你是个讲究人,或者处理的数据量特别大,得考虑点性能和内存问题了。这时候,extend() 方法就该登场了。
“`python
list_a = [1, 2, ‘猫’]
list_b = [‘狗’, 4, 5]
list_a.extend(list_b)
现在,list_a 自己变成了 [1, 2, ‘猫’, ‘狗’, 4, 5]
“`
看明白区别没?extend() 是个“原地操作”,它不会创建新列表,而是把 list_b 里的元素,一个个地“追加”到 list_a 的屁股后面。这么做的好处是节省内存,因为它没有生成那个额外的 new_list。当你的列表大到能塞满几个G内存的时候,这点差距,就是程序“健步如飞”和“原地喘气”的区别。
所以,怎么选?小打小闹,数据量不大,或者你不希望原始列表被修改,用 + 号,痛快!处理海量数据,或者你就是想在原有列表上进行扩展,extend() 是你的不二之M。
字典(Dict)的归并:真正的战场
列表的归并,说白了就是小孩子过家家。真正的硬仗,还得看字典(Dictionary)。这玩意儿有键(key),有值(value),合并起来的讲究就多了。
假设我们有俩字典:
python
dict_a = {'name': '张三', 'age': 25}
dict_b = {'age': 26, 'city': '北京'}
注意,他俩有个共同的键 age。这下问题就来了,合并之后,age 到底听谁的?
老派绅士:update() 方法
在Python比较早的版本里,update() 是主流。它跟列表的 extend() 有点像,也是个原地操作。
“`python
dict_a.update(dict_b)
dict_a 就变成了 {‘name’: ‘张三’, ‘age’: 26, ‘city’: ‘北京’}
“`
update() 的规则很简单粗暴:把 dict_b 合并到 dict_a 里。如果遇到相同的键(比如 age),后面来的(dict_b)说了算,直接覆盖掉前面的。dict_a 被永久地改变了。
现代语法糖:解包 ** 与合并 |
但现在都什么年代了,总用 update() 显得有点……复古。Python 3.5 之后,我们可以用更骚气的解包操作符 **。
“`python
merged_dict = {dict_a, dict_b}
merged_dict 成了 {‘name’: ‘张三’, ‘age’: 26, ‘city’: ‘北京’}
“`
这一行代码,简直是艺术!它做的事情和 update() 类似,但它创建了一个全新的字典 merged_dict,原始的 dict_a 和 dict_b 毫发无损。对于重复的键,规则也是一样:写在后面的说了算。这种写法不仅优雅,而且意图明确,是现在社区里更推崇的玩法。
你以为这就完了?天真。到了Python 3.9,好家伙,官方直接给了一个大杀器——合并运算符 |。
“`python
这需要 Python 3.9 或更高版本
merged_dict = dict_a | dict_b
merged_dict 也是 {‘name’: ‘张三’, ‘age’: 26, ‘city’: ‘北京’}
“`
看到了吗?一个竖线,干了 ** 解包同样的事。不能说一模一样,简直是毫无差别。这纯粹就是为了让代码更简洁,更符合数学上“并集”的直觉。如果你和你的团队用的都是比较新的Python版本,大胆用 | 吧,这玩意儿是未来的趋势。
所以字典归并,我个人强烈站队 ** 解包和 |** 运算符。它们不修改原始数据,这在编程里是个非常好的习惯,能避免很多意想不到的bug。除非你真的有强烈的需求,要“就地”修改一个字典,否则,离 update() 稍微远一点。
终极武器:Pandas 的归并
前面说的,都是Python内置数据结构的小打小闹。当你的数据升级到“表”这个级别,比如你有两个Excel表,两个CSV文件,里面存着成千上万条结构化数据,这时候,就该请出数据科学界的瑞士军刀——Pandas了。
用Pandas来讨论python怎么归并,那格局一下就打开了。它提供的 merge 函数,简直就是为数据整合而生的神兵利器。
想象一下,你有一张学生信息表(students),有学号、姓名。还有一张成绩表(scores),有学号、科目、分数。你想把这两张表根据“学号”关联起来。
“`python
import pandas as pd
students = pd.DataFrame({‘学号’: [1, 2, 3], ‘姓名’: [‘小明’, ‘小红’, ‘小刚’]})
scores = pd.DataFrame({‘学号’: [1, 2, 4], ‘科目’: [‘数学’, ‘语文’, ‘数学’], ‘分数’: [95, 88, 76]})
见证奇迹的时刻
merged_df = pd.merge(students, scores, on=’学号’, how=’inner’)
“`
pd.merge() 这一招,可比前面的所有方法都复杂,也强大得多。简单解释一下几个关键参数:
left和right: 就是你要合并的两个DataFrame(可以想象成两张表)。on: 指定依据哪个(或哪些)列来合并。这里是’学号’。how: 这才是精髓!指定合并的方式。inner(内连接):只保留两张表中“学号”都存在的行。所以学号为3的小刚(没成绩)和学号为4的某位同学(没姓名)都被扔掉了。这是默认方式。outer(外连接):不管三七二十一,两张表里所有的数据都保留,能对上的就对上,对不上的地方用NaN(空值) 填充。一个都不能少。left(左连接):以左边的表(students)为准,保留所有学生的信息。成绩表里有对应的,就填上;没有的(比如小刚),成绩相关字段就填NaN。right(右连接):跟左连接反过来,以右边的表(scores)为准。
Pandas的 merge 就像一个精密的数据库连接工具,它让你能够以极其灵活的方式,处理复杂的数据对齐和整合问题。当你面对的不再是零散的几个键值对,而是结构化的数据集时,别犹豫,Pandas merge 就是你的答案。
归根结底,Python怎么归并这个问题,没有唯一的标准答案。它考验的是你对场景的判断。是想图个省事,还是得抠内存?是希望保留原始数据,还是就地修改?是处理简单的序列,还是复杂的结构化表格?
从 + 的直截了当,到 extend() 的精打细算,再到 ** 和 | 的优雅现代,最后到 pandas.merge 的专业强大。掌握这些“招式”,你才能在不同的数据整理场景中,像个真正的老手一样,游刃有余,选择最恰当、最漂亮的那一手。
