2017-08-13 54 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]