首页 > 解决方案 > 关于使用 setitem 的地图功能的建议

问题描述

我正在努力理解“Python Book”中的脚本。该脚本通过将每个元素作为键(例如'none'作为值)放入字典中来从列表中删除重复项,然后返回dict.keys(). 脚本如下:

from operator import setitem
def distinct(l):
    d = {}
    map(setitem, (d,)*len(l), l, [])
    return d.keys()

我已经运行了脚本,将包含重复项的列表传递给distinct()

li = [1, 5, 6, 1, 8]
x = distinct(li)
print(x)

但是,当我运行脚本并打印结果时,我得到了:

dict_keys([])

有人可以给我一个如何运行该distinct()函数的示例,以便获得一些有意义的输出吗?也请有人解释一下 map 函数如何与内部setitem函数一起工作。我已经阅读过setitem,但我不确定它是如何在这里工作的。我对第一个论点感到困惑setitem

(d,)*len(l)

标签: pythondictionary

解决方案


正如所写的那样,distinct不能在 Python 3 中工作,因为在这种情况下,map一个setitem返回一个可迭代的对象,该可迭代对象将在您对其进行迭代时按需调用。由于返回值被忽略,setitem永远不会被调用。

在 Python 2 中,map有一个函数的行为很像列表推导:它通过调用setitem给定迭代的元素返回一个返回值列表。map但是,仅仅为了函数的副作用而使用(或列表理解)从未被认为是好的做法。

如果您不关心生成的序列或列表,请使用适当的for循环,而不是创建map永远不会迭代的实例。

def distinct(l):
    d = {}
    for k in l:
        d[k] = None
    return list(d)

或使用 dict 理解:

def distinct(l):
    return list({k: None for k in l})

的目的(d,)*len(l)是创建引用序列d,以便每次调用都setitem修改相同dict

调整我的第一个示例以使用setitem看起来像

def distinct(l):
    d = {}
    for k in l:
        setitem(d, k, None)
    return list(d)

请注意,list(map(setitem, (d,)*len(l), l, []))永远不会做任何事情。[]是第三个可迭代对象,其内容,而不是列表本身,将用作 . 的第三个参数setitemmap仅迭代直到用尽最短的可迭代对象,并且空列表将立即用尽。


推荐阅读