使用列表推导使函数更加pythonic

时间:2015-10-13 14:51:57

标签: python python-2.7 list-comprehension

我正在做一些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 = [])有点奇怪,所以在这种情况下使用列表推导可能无法做到这一点。

2 个答案:

答案 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, [])