地图返回所有列表无

时间:2019-08-21 00:40:29

标签: python lambda

我正在尝试编写一个简单的python代码,该代码将使用最大堆找到最接近原始元素的列表k。我的主要问题是关于在python中使用地图的问题,我尝试以此方式进行编码,并且我得到了None的列表作为输出,而我希望max_heap会填充由heappush推送的值/ heappushpop。有人可以指出这里有什么问题吗?另外,我想知道是否真的需要将max_heap声明为空列表?有没有一种方法可以用1条语句编写整个逻辑?谢谢!

def find_closest_k_nums(nums, k):
    max_heap = []
    for num in nums:
        if len(max_heap) == k + 1:
            heapq.heappushpop(max_heap, -num)
        else:
            heapq.heappush(max_heap, -num), nums
    return [-s for s in heapq.nlargest(k, max_heap)]
# >>> find_closest_k_nums([1, 5, 6, 3, 8, 9, 10], 4) => [1, 3, 5, 6]

# I tried to write the above function using map but I got an empty list.
def find_closest_k_nums_with_map(nums, k):
    max_heap = []
    map(lambda x: heapq.heappushpop(max_heap, -x)
        if len(max_heap) == k + 1 else heapq.heappush(max_heap, -x), nums)
    return [-s for s in heapq.nlargest(k, max_heap)]
# >>> find_closest_k_nums_with_map([1, 5, 6, 3, 8, 9, 10], 4) => []

1 个答案:

答案 0 :(得分:1)

map返回一个可迭代对象,当您从可迭代对象中请求元素时,它会按需调用函数 。更简单:

>>> def increment(x):
...   print(f"Calling increment on {x}")
...   return x + 1
...
>>> x = [1,2,3]
>>> y = map(increment, x)

直到您遍历y为止,都不会调用increment。只有当您在next上呼叫y时,increment才会被呼叫。

>>> next(y)
Calling increment on 1
2
>>> next(y)
Calling increment on 2
3

要在第二个函数中将nums的元素添加到堆中,您需要(以某种方式)遍历map将产生的元素。例如,将map对象传递到list以强制迭代:

def find_closest_k_nums_with_map(nums, k):
    max_heap = []
    list(map(lambda x: heapq.heappushpop(max_heap, -x)
        if len(max_heap) == k + 1 else heapq.heappush(max_heap, -x), nums))
    return [-s for s in heapq.nlargest(k, max_heap)]

但这是可怕的风格。您实际上对映射到nums上的函数的返回值并不感兴趣,而只是更新max_heap的副作用。在这种情况下,只需在第一个函数中使用for循环即可。