【问题标题】:Equivalent of Lua's pairs() for Python等价于 Python 的 Lua 的 pairs()
【发布时间】:2020-01-27 21:48:05
【问题描述】:

我需要一个通用 API 来将 Python 对象迭代为键/索引和值对。这样:

for k,v in pairs({"foo": "bar"}):
    print(k, v)

输出“foo bar”,并且

for i,v in pairs(["foo", "bar"]):
    print(i, v)

输出“0 foo”和“1 bar”,就像 Lua 等效项一样(除了针对 0 索引和 1 索引进行了更正)。

这样的 API 存在吗?

【问题讨论】:

  • 你需要{"foo": "bar"}.items()
  • @Jean-FrançoisFabre 不适用于列表或元组。
  • 没有一个函数的行为方式与您描述的方式相同。使用items 方法进行映射,enumerate 用于类似列表的可迭代对象。
  • @SoniEx2:你为什么需要一个“通用 API”?在不知道类型是字典还是列表的情况下,您在做什么? Python 不是 Lua,您不应该像 Lua 代码那样编写 Python 代码。学习一门新的编程语言最重要的部分之一是学习它的惯用语,即用该语言编写代码的方式。只有在万不得已的情况下才应该从另一种语言导入习语。这不是“需要”;这是个人喜好。
  • @NicolBolas 配置文件。实际上,Lua 的语义是正确的。

标签: python python-3.x lua iteration


【解决方案1】:

您可以通过测试输入类型来模拟“pairs”函数,并在字典的情况下使用items,在列表、元组的情况下使用enumerate,或者默认为enumerate,这将适用于任何可迭代:

def pairs(o):
    if isinstance(o,dict):
        return o.items()
    else:
        return enumerate(o)


for k,v in pairs({"foo": "bar"}):
    print(k, v)
for i,v in pairs(["foo", "bar"]):
    print(i, v)

打印:

foo bar
0 foo
1 bar

另外:更改为 return enumerate(o,1) 以使索引从 1 开始。

【讨论】:

  • @chepner 处理异常比if-test 更昂贵。如果异常频繁发生,if-else 语句更合适。
  • 首先调用pairs(并检测在运行时使用哪个惯用语,而不是首先简单地编写类型感知代码)也很昂贵。
  • 大多数时候使用字典类型调用异常解决方案会更快。
【解决方案2】:

对于dict,使用items 方法:

for k, v in {"foo": "bar"}.items():
    print(k, v)

列表没有等价物。不过,您可能需要查看itertools documentation 中的石斑鱼食谱。

要将字典转换为可与grouper 一起使用的可迭代对象,请使用itertools.chain.from_iterable({"a": 1, "b": 2}.items())

【讨论】:

  • 不,我不是想将列表迭代为值对,而是作为 (index,value) 对(如enumerate)。
  • 然后使用enumerate。没有理由应该有一个函数来执行两个不相关的事情,例如 pairs 似乎可以做到。
猜你喜欢
  • 2021-02-16
  • 2018-02-04
  • 2011-12-08
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2011-08-18
  • 2010-12-15
  • 2012-06-28
相关资源
最近更新 更多