2017-08-13 11 views
1

私は辞書のリストを持っています。リスト内の各辞書には、例えば、同じキーを持っていますが、それぞれが異なる値を持っていますPython:リスト+ラムダの振る舞い

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

私は新しいキーnew_key2key2を交換するには、次を使用:

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 

なぜですか? 'list + map'関数でリストを取得してはいけませんか?

+3

あなたのラムダ関数は、それはちょうどあなたがあなたのリストは次のようになりたいです何リスト – AK47

+0

を更新任意の値を返すイマイチ? –

答えて

2

update文の結果がNoneあるような何かを行います。 map機能でlistに電話する必要はありません。この機能は、mylistの各項目を更新しています。

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) 

そのまま結果を代入する必要はありませんが、 None値のリストだけです。

2

ラムダ関数は何も返しません。リストを更新するだけです。このコードブロックを見てください。

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}] 

あなたは、この新しいリストに対応する新しい変数を持つようにしたい場合は、返された結果が[None, None, None]あるので、なぜ、

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

これを行うには2通りの方法があります。最初は(私はこれをお勧めしません第二は、副作用なしでより純粋な機能的なアプローチである

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] 

既存の辞書を変更する(そしてあなたがNoneに対処する必要はありませんので、辞書への参照を返します)実際のアプリケーションのために、それははるかに少ないefficentです)

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