簡體   English   中英

映射python字典中的值

[英]Mapping over values in a python dictionary

給定字典{ k1: v1, k2: v2 ... }我想得到{ k1: f(v1), k2: f(v2) ... }如果我傳遞了一個函數f

有沒有這樣的內置功能? 還是我必須做

dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])

理想情況下我會寫

my_dictionary.map_values(f)

或者

my_dictionary.mutate_values_with(f)

也就是說,原始字典是否發生變異或創建副本對我來說並不重要。

沒有這樣的功能; 最簡單的方法是使用字典理解:

my_dictionary = {k: f(v) for k, v in my_dictionary.items()}

在 python 2.7 中,使用.iteritems()方法而不是.items()來節省內存。 dict 理解語法直到 python 2.7 才引入。

請注意,列表中也沒有這種方法; 您必須使用列表理解或map()函數。

因此,您也可以使用map()函數來處理您的 dict:

my_dictionary = dict(map(lambda kv: (kv[0], f(kv[1])), my_dictionary.iteritems()))

但這不是那么可讀,真的。

這些工具非常適合這種簡單但重復的邏輯。

http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap

讓你在你想去的地方。

import toolz
def f(x):
  return x+1

toolz.valmap(f, my_list)

您可以就地執行此操作,而不是創建新的字典,這對於大型字典可能更可取(如果您不需要副本)。

def mutate_dict(f,d):
    for k, v in d.iteritems():
        d[k] = f(v)

my_dictionary = {'a':1, 'b':2}
mutate_dict(lambda x: x+1, my_dictionary)

導致my_dictionary包含:

{'a': 2, 'b': 3}

由於PEP-0469將 iteritems() 重命名為 items() 和PEP-3113刪除了Tuple 參數 unpacking ,在 Python 3.x 中,您應該像這樣編寫Martijn Pieters♦ 答案

my_dictionary = dict(map(lambda item: (item[0], f(item[1])), my_dictionary.items()))

雖然我的原始答案沒有抓住重點(通過嘗試使用在 defaultdict 工廠中訪問密鑰的解決方案來解決這個問題),但我已經對其進行了重新設計,以提出當前問題的實際解決方案。

這里是:

class walkableDict(dict):
  def walk(self, callback):
    try:
      for key in self:
        self[key] = callback(self[key])
    except TypeError:
      return False
    return True

用法:

>>> d = walkableDict({ k1: v1, k2: v2 ... })
>>> d.walk(f)

這個想法是對原始 dict 進行子類化以賦予它所需的功能:在所有值上“映射”一個函數。

優點是這個字典可以用來存儲原始數據,就好像它是一個dict一樣,同時通過回調轉換任何請求的數據。

當然,請隨意以您想要的方式命名類和函數(此答案中選擇的名稱受到 PHP 的array_walk()函數的啟發)。

注意: try - except塊和return語句對於該功能都不是強制性的,它們是為了進一步模仿 PHP 的array_walk的行為。

為了避免從 lambda 內部進行索引,例如:

rval = dict(map(lambda kv : (kv[0], ' '.join(kv[1])), rval.iteritems()))

你也可以這樣做:

rval = dict(map(lambda(k,v) : (k, ' '.join(v)), rval.iteritems()))

剛剛遇到這個用例。 我實現了gens's answer ,添加了一種遞歸方法來處理也是 dicts 的值:

def mutate_dict_in_place(f, d):
    for k, v in d.iteritems():
        if isinstance(v, dict):
            mutate_dict_in_place(f, v)
        else:
            d[k] = f(v)

# Exemple handy usage
def utf8_everywhere(d):
    mutate_dict_in_place((
        lambda value:
            value.decode('utf-8')
            if isinstance(value, bytes)
            else value
        ),
        d
    )

my_dict = {'a': b'byte1', 'b': {'c': b'byte2', 'd': b'byte3'}}
utf8_everywhere(my_dict)
print(my_dict)

這在處理在 Python 2 中將字符串編碼為字節的 json 或 yaml 文件時很有用

  • 我映射字典的方式
def f(x): return x+2
bill = {"Alice": 20, "Bob": 10}
d = {map(lambda x: f(x),bill.values())}
print('d: ',dict(d))

結果

: d:  {22: 12}
  • 映射字典中的值中的可迭代
bills = {"Alice": [20, 15, 30], "Bob": [10, 35]}
d= {map(lambda v: sum(v),bills.values())}
g= dict(map(lambda v: (v[0],sum(v[1])),bills.items()))
# prints
print('d: ',dict(d))
print('g: ',g)

結果

d:  {65: 45}
g:  {'Alice': 65, 'Bob': 45}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM