将列表理解转换为功能编程

发布于 2025-01-23 21:54:08 字数 543 浏览 0 评论 0原文

我有每个字典中每个键的字典列表

lst = [{'a': (1, 2, 3), 'b': (2, 3)},
       {'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
       {'d': (6, 12), 'e': (7, 14)}]

,我只想保留值的第一个元素。因此,所需的输出是

[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]

我可以使用列表理解的列表来获得它

[{key: val[0] for key, val in dct.items()} for dct in lst]

,但是我想知道是否可以使用地图,ItemGetter,Itertools,functools等获得相同的输出。到目前为止,我所拥有的内容:

map(dict.values, lst)

但是我不知道如何从这里去。

I have a list of dictionaries

lst = [{'a': (1, 2, 3), 'b': (2, 3)},
       {'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
       {'d': (6, 12), 'e': (7, 14)}]

For each key in each dictionary, I want to keep only the first element of the values. So the desired output is

[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]

I can get it using a list comprehension like

[{key: val[0] for key, val in dct.items()} for dct in lst]

However, I want to know if it's possible to get the same output using map, itemgetter, itertools, functools etc. What I have so far:

map(dict.values, lst)

But I don't know how to go from here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落花随流水 2025-01-30 21:54:08

对于嵌套的迭代,我认为没有Lambda表达的帮助,我们无法做到:

from operator import itemgetter, methodcaller

list(map(
     lambda items: dict(zip(
             map(itemgetter(0), items),
             map(itemgetter(0), map(itemgetter(1), items))
         )), map(methodcaller('items'), lst)))
# [{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]

我不得不说这很丑陋。

更新:
我找到了一种避免lambda的方法:

  1. 首先,根据评论区域,我们简化了上述表达式(此处省略了最外面的列表以减少理解的难度):
func = lambda d: dict(zip(d, map(itemgetter(0), d.values())))
map(func, lst)
  1. 很容易观察到dict>可以在Lambda外移动。我们只需要添加另一个MAP
func = lambda d: zip(d, map(itemgetter(0), d.values()))
map(dict, map(func, lst))
  1. 同样,我们可以移动Zip外部lambda:
func = lambda d: map(itemgetter(0), d.values())
map(dict, map(zip, lst, map(func, lst)))
  1. 这似乎是结束的,似乎没有办法将lambda转换为多个内置功能的组合,但是仍然有一些方法,让我们首先尝试移动d.Values在lambda之外。在这里,由于确定了列表的元素类型,因此我们直接使用dict.values而不是operator.methodcaller
func = lambda values: map(itemgetter(0), values)
map(dict, map(zip, lst, map(func, map(dict.values, lst))))
  1. 答案已准备就绪。我们可以使用functools.partial
map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))

测试:

>>> from operator import itemgetter
>>> from functools import partial
>>> lst = [{'a': (1, 2, 3), 'b': (2, 3)},
...        {'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
...        {'d': (6, 12), 'e': (7, 14)}]
>>> map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))
<map object at 0x000002A0542CBB20>
>>> list(_)
[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]

For nested iterations, I don't think we can do it without the help of lambda expressions:

from operator import itemgetter, methodcaller

list(map(
     lambda items: dict(zip(
             map(itemgetter(0), items),
             map(itemgetter(0), map(itemgetter(1), items))
         )), map(methodcaller('items'), lst)))
# [{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]

I have to say it's very ugly.

Update:
I found a way to avoid lambda:

  1. First, according to the comment area, we simplify the above expression (the outermost list is omitted here to reduce the difficulty of understanding):
func = lambda d: dict(zip(d, map(itemgetter(0), d.values())))
map(func, lst)
  1. It is easy to observe that dict can be moved outside lambda. We just need to add another map:
func = lambda d: zip(d, map(itemgetter(0), d.values()))
map(dict, map(func, lst))
  1. Similarly, we can move the zip outside lambda:
func = lambda d: map(itemgetter(0), d.values())
map(dict, map(zip, lst, map(func, lst)))
  1. This seems to be the end, and there seems to be no way to convert lambda into a combination of multiple built-in functions, but there are still ways, let's first try to move d.values outside lambda. Here, since the element type of the list is determined, we directly use dict.values instead of operator.methodcaller:
func = lambda values: map(itemgetter(0), values)
map(dict, map(zip, lst, map(func, map(dict.values, lst))))
  1. The answer is ready to come out. We can eliminate lambda by using functools.partial:
map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))

Test:

>>> from operator import itemgetter
>>> from functools import partial
>>> lst = [{'a': (1, 2, 3), 'b': (2, 3)},
...        {'c': (3, 6), 'd': (4, 8), 'e': (5, 10)},
...        {'d': (6, 12), 'e': (7, 14)}]
>>> map(dict, map(zip, lst, map(partial(map, itemgetter(0)), map(dict.values, lst))))
<map object at 0x000002A0542CBB20>
>>> list(_)
[{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}, {'d': 6, 'e': 7}]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文