能否在Python列表推导式与map中访问正在构建的自身列表?
问题背景
先看这段Python代码:
chars = ["a", "a", "b"] added = [] for c in chars: if c in added: added.append(c + '_added_again') else: added.append(c) # 最终added结果是 ['a', 'a_added_again', 'b']
这段循环的逻辑是:遍历chars的每个字符,判断当前字符是否已经在正在构建的added列表中,如果是就添加带后缀的版本,否则直接添加原字符。
现在有两个疑问:
- 能不能用列表推导式复现这个行为?比如类似下面的写法,有没有办法在推导式里访问到正在构建的列表?
chars = ["a", "a", "b"] added = [ c + '_added_again' if c in {类似`self`或`this`的对象,或可用lambda?} else c for c in chars ]
- 同样的,能不能用
map函数实现?在map的lambda里能不能访问到正在构建的列表?
added = list(map(lambda x: x + '_added_again' if ??? else x, chars))
解答
严格来说,常规的列表推导式和map函数都无法直接访问正在构建的列表:
- 列表推导式是一次性生成所有元素的语法糖,在推导过程中,最终的列表还未完全创建,推导式内部无法直接引用这个还在生成中的列表对象。
map函数是逐个处理输入元素,处理每个元素时,最终要转换的列表也还没生成,lambda表达式里同样拿不到这个列表。
不过可以用一个**外部可变对象(比如列表)**来模拟原逻辑的状态,间接实现效果,比如:
用列表推导式模拟
chars = ["a", "a", "b"] seen = [] added = [c + '_added_again' if c in seen else seen.append(c) or c for c in chars]
这里的原理是:seen.append(c)会返回None,所以seen.append(c) or c会取到c,同时把当前字符c存入seen列表,以此模拟原循环中added列表的状态(判断字符是否已出现过)。
用map函数模拟
chars = ["a", "a", "b"] seen = [] added = list(map(lambda x: x + '_added_again' if x in seen else (seen.append(x) or x), chars))
逻辑和上面一致,用seen记录已经处理过的字符,lambda里根据这个判断返回对应结果。
但要注意:这种方法是借助外部变量实现的,并非直接访问正在构建的added列表,本质上是用额外的状态容器替代了原循环中added的判断作用。
内容的提问来源于stack exchange,提问作者rzlvmp
相关产品推荐
相关产品推荐

