2017-08-13 21 views
1

我有一个词典列表。列表中的每个字典有相同的密钥,但每个人都有不同的值,例如:Python:列表+ lambda行为

my_list = [ 
    {key1: 100, key2: 110, key3: 120}, 
    {key1: 200, key2: 210, key3: 220}, 
    {key1: 300, key2: 310, key3: 320}] 

我用下面的一个新的密钥new_key2更换key2

list(map(lambda x: x.update({"new_key2": x.pop("key2")}), my_list)) 

代码工作和my_list是但我无法理解以下行为:

my_list = list(map(lambda x: x.update({"new_key2" : x.pop ("key2")}), my_list)) 

在这种情况下返回my_list返回以下值:

my_list[0] = None 
my_list[1] = None 
my_list[2] = None 

为什么?不应该'列表+地图'功能检索我的列表?

+3

你的lambda函数返回的心不是,它只是更新列表 – AK47

+0

任何值,你要什么你的列表是什么样子? –

回答

2

一个update语句的结果是None,因此为什么返回的结果是[None, None, None]map函数不需要调用list。此功能正在更新mylist中的每个项目。

我相信下面的代码更pythonic,也处理的情况下,当没有key2。变量mylist是就地修改的,因此不需要将其重新分配给列表。与重新分配列表理解的结果相比,下面的方法稍微更有效率。

for d in mylist: 
    try: 
     d['new_key2'] = d.pop('key2') 
    except KeyError: 
     pass # no 'key2' 

>>> mylist 
[{'key1': 100, 'key3': 120, 'new_key2': 110}, 
{'key1': 200, 'key3': 220, 'new_key2': 210}, 
{'key1': 300, 'key3': 320, 'new_key2': 310}] 

如果你喜欢使用map方法(这是在这种情况下更快),我提出以下建议:

map(lambda x: 
    x.update({"new_key2": x.pop("key2")}) 
    if 'key2' in x else None, mylist) 

没有必要分配的结果,因为它是只是一个无值的列表。

2

你的lambda函数不返回任何东西,它只是更新列表。看看这块代码。

In [15]: mylist = [ 
    {'key1' : 100, 'key2' : 110, 'key3' : 120}, 
    {'key1' : 200, 'key2' : 210, 'key3' : 220}, 
    {'key1' : 300, 'key2' : 310, 'key3' : 320}] 

In [16]: list(map(lambda x: x.update({"mewkey2" : x.pop ("key2")}), mylist)) 
Out[16]: [None, None, None] 

In [17]: mylist 
Out[17]: 
[{'key1': 100, 'key3': 120, 'mewkey2': 110}, 
{'key1': 200, 'key3': 220, 'mewkey2': 210}, 
{'key1': 300, 'key3': 320, 'mewkey2': 310}] 

如果你想拥有对应于该新列表中的新变量,这样做

newlist = mylist[::] 
list(map(lambda x: x.update({"mewkey2" : x.pop ("key2")}), newlist)) 
0

所以有两种方法可以做到这一点。第一次修改现有的字典(并返回到字典中的引用,因此您不必处理None

def replace_key(old_key, new_key, d): 
    d[new_key] = d.pop('old_key') 
    return d 

mylist = [replace_key('key2', 'newkey2', d) for d in mylist] 

二是无副作用更纯功能性的做法(我不会推荐对于实际应用,它更efficent)

mylist = [{k : v if k != 'key2' else 'newkey2': v for k, v in d.items()} for d in mylist]