我正在做一些Google Python Class练习,我正在尝试找到解决以下问题的pythonic解决方案。
d。给定一个数字列表,返回一个列表,其中所有相邻的== 元素已减少为单个元素,因此[1,2,2,3] 返回[1,2,3]。您可以创建新列表或修改传入的内容 列表。
我的尝试,完美运作如下:
def remove_adjacent(nums):
result = []
for num in nums:
if len(result) == 0 or num != result[-1]:
result.append(num)
return result
例如,remove_adjacent([2, 2, 3, 3, 3])
输出为[2, 3]
。一切都好。
我正在尝试使用列表推导来以更加 pythonic 的方式来实现这一点,所以我的尝试如下:
def remove_adjacent(nums):
result = []
result = [num for num in nums if (len(result)==0 or num!=result[-1])]
return result
使用相同的输入[2, 2, 3, 3, 3]
,输出为[2, 2, 3, 3, 3]
(相同)。 Meeeh!错。
我在列表推导方面做错了什么?我是否尝试做一些与列表推导无关的事情?我知道初始化列表(result = []
)有点奇怪,所以在这种情况下使用列表推导可能无法做到这一点。
答案 0 :(得分:11)
我是否尝试做一些与列表推导无关的事情?
是的。列表理解不能通过名称来引用自身,因为变量在完全完成评估之前根本不受约束。这就是为什么如果你的第二个代码块中没有NameError
,你会获得result = []
的原因。
如果不使用标准模块作弊,请考虑使用groupby
将列表中的相似值组合在一起:
>>> import itertools
>>> seq = [1, 2, 2, 3]
>>> [k for k,v in itertools.groupby(seq)]
[1, 2, 3]
>>> seq = [2,2,3,3,3]
>>> [k for k,v in itertools.groupby(seq)]
[2, 3]
答案 1 :(得分:2)
为了学习,我建议使用核心reduce
函数:
def remove_adjacent(lst):
return reduce(lambda x, y: x+[y] if not x or x[-1] != y else x, lst, [])