使用extend方法合并字典列表:列表推导式返回None的原理
为什么列表推导式里用
extend会返回[None, None]? 咱们先把场景再理一遍:你有个字典d = {'foo':['c', 'a', 't'], 'bar':['d', 'o', 'g']},想要把字典里所有值列表的元素合并成一个大列表['c', 'a', 't', 'd', 'o', 'g']。
用循环调用extend的写法完全没问题:
l = [] for i in d.values(): l.extend(i) print(l) # 输出: ['c', 'a', 't', 'd', 'o', 'g']
但换成列表推导式[ [].extend(i) for i in d.values() ]就得到了[None, None],核心原因其实很简单:
关键:list.extend()是原地修改,返回None
Python里很多原地修改容器的方法(比如list.append()、list.sort()、dict.update())都遵循一个规则:它们会直接修改原对象,但不会返回修改后的对象,而是返回None。
你写的列表推导式里,每次都会创建一个新的空列表[],然后调用extend(i)给这个临时列表添加元素——这个操作确实修改了那个临时列表,但方法本身返回的是None。推导式的作用是收集每次迭代中表达式的返回值,所以最终就得到了两个None(对应字典里的两个值列表),而且那个被修改的临时列表用完就被丢弃了,根本没保留下来。
那怎么用一行代码实现需求?
如果你想用一行代码完成合并,有几种更合适的写法:
方法1:嵌套列表推导式展开
这是最直观的纯Python写法,不需要额外导入模块:
l = [item for sublist in d.values() for item in sublist]
方法2:用itertools.chain(适合处理大量数据)
如果你的字典里有很多大列表,用itertools.chain效率更高,因为它不会创建中间列表:
import itertools l = list(itertools.chain.from_iterable(d.values()))
方法3:用sum(不推荐大量数据)
这个写法比较简洁,但因为sum会不断创建新列表,数据量大的时候效率很低:
l = sum(d.values(), [])
内容的提问来源于stack exchange,提问作者Wizard
相关产品推荐
相关产品推荐

