【问题标题】:Python : List + lambda behaviourPython:列表 + lambda 行为
【发布时间】:2017-08-13 19:51:19
【问题描述】:

我有一个字典列表。列表中的每个字典都有相同的键但每个都有不同的值,例如:

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

我使用以下代码将 key2 替换为新密钥 new_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

为什么? 'list + map' 函数不应该检索我一个列表吗?

【问题讨论】:

  • 你的 lambda 函数没有返回任何值,它只是更新列表
  • 您希望您的列表是什么样的?

标签: python list dictionary lambda


【解决方案1】:

update 语句的结果是None,因此返回的结果是[None, None, None]。无需在map 函数上调用list。此函数正在更新mylist 中的每个项目。

我相信下面的代码更符合 Python 风格,并且还可以处理没有 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】:

    您的 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))
    

    【讨论】:

      【解决方案3】:

      所以有两种方法可以做到这一点。第一个修改现有字典(并返回对字典的引用,因此您不必处理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]
      

      第二种是没有副作用的更纯粹的函数式方法(我不建议在实际应用中使用这种方法,它的效率要低得多)

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

      【讨论】:

        猜你喜欢
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-24
        • 2013-03-26
        相关资源
        最近更新 更多