python - 如何在整个迭代中应用函数?

标签 python data-structures iterator

我想要函数f该工作风格是:

>>> f(chr, [65, 97])
['A', 'a']
>>> f(chr, {65, 97})
{'A', 'a'}
>>> f(chr, {65: 'upper_a', 97: 'lower_a'})
{'A': 'upper_a', 'a': 'lower_a'}

map很懒,所以我必须这样做list(map(function, iterable_ds)) ,但这种方式破坏了原始数据结构。

你怎么能做到这一点?

<小时/>

有一天尝试写f ,我有这个问题吗?

每个带有 __iter__ 的数据结构类是可迭代的,但像 __next__()给出任何可迭代中的下一个元素,那么什么特殊函数将使 upower 将任何 xyz 添加到可迭代 d.s.?为什么append仅用于列表而add用于集合?为什么没有像__iter__这样的通用接口(interface)和__next__

<小时/>

我试过了

def f(func, i_ds):
    ctor = type(i_ds)
    holder = list()
    for _ in i_ds:
        new_val = func(_)
        # now what add? append? update? xyz? I hope ctor can consume list
        holder.append(new_val)
    return ctor(holder) # I know I know it fail for dict type easily

我可以写 f 来处理 dict 但是

  • 很丑
  • 如果明天我得到 2 棵树怎么办?由不同的人写的

最佳答案

映射(类似 dict 的东西)与其他集合根本不同,因此您无法完全避免对它们进行特殊的大小写,但您至少可以限制所需的专用代码的数量。虽然您说得对,没有通用的“将项目添加到集合”API,但大多数集合都接受构造函数的可迭代值。

使用基于构造函数的鸭子类型,对您所获得的内容进行一个小小的改进:

import collections.abc

def f(func, it):
    res = map(func, it)
    if isinstance(it, collections.abc.Mapping):
        # Pair up mapped keys with original values
        res = zip(res, it.values())
    return type(it)(res)

这不需要任何中间临时数据结构(mapzip是基于惰性生成器的函数;它们仅在最后构造返回类型时才产生值)。它假设所有非 Mapping 类型都可以从可迭代的值构造,而所有 Mapping 类型都可以从可迭代的对构造;对于通用内置集合( tuplelistsetfrozensetdict ),情况就是如此。不太通用的容器不一定能工作( bytes 将取决于 func 的结果,如果没有特殊的外壳来使用 str''.join 将无法工作)。

也就是说,您尝试做的事情是不必要的。您的 f 函数正在复制 map ,情况很糟糕。由于不可能编写像您这样具有完美类型复制的函数,因此最好像 map 那样做,并将其留给调用者以任何合适的数据结构重新打包结果(例如,对于 dict s,它们可以显式传递映射期望键/值 tuple 并传递 .items() 的函数,然后从结果构造 dict ;实际上他们可能需要 dict 理解)。

毕竟,您所要求的永远不会适用于每种输入类型,仅仅是因为构造函数并不总是遵循相同的规则。例如,此代码不适用于 collections.defaultdict,因为它将 default_factory 作为第一个参数,第二个是可迭代初始值设定项(违反了我们对第一个参数是可迭代初始值设定项的期望)。尝试处理这个问题意味着更多的特殊情况,而且你只会让确定 f 实际作用变得越来越困难。调用者明确执行以下操作真的那么困难吗: {myfunc(k): v for k, v in mydict.items()} 而不是 f(myfunc, mydict) ,或者 [myfunc(x) for x in mylist]/list(map(myfunc, mylist)) over f(myfunc, mylist)

关于python - 如何在整个迭代中应用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51941464/

相关文章:

javascript - 在 jQuery 中使用 next() x 次

c++ - 将 `auto` 关键字与 STL 迭代器一起使用

python - 使用 session.query 读取 SQLAlchemy 中未提交的数据

python - 如何检查我的一列值是否存在于另一列中

java - 我将如何访问我在 Java 中的 TreeMap 中放置元素的顺序?

algorithm - 如何将大型二分图用户-项目转换为项目-项目?

algorithm - 按优先级对双向单元格连接进行排序

使用迭代器的 Lua 迭代器

python - 谷歌应用引擎 : How to write large files to Google Cloud Storage

Python,如何从存储在数据库中的类中实例化类?