【问题标题】:How to transform a list {element,...} to a list of tuples {{i,element},...}?如何将列表 {element,...} 转换为元组列表 {{i,element},...}?
【发布时间】:2023-03-18 21:44:01
【问题描述】:

给定一些列表

numbers = {2,3,5,7,11,13};

如何翻译成

translatedNumbers = {{1,2},{2,3},{3,5},{4,7},{5,11},{6,13}}

简明扼要?

我知道如何使用以下程序式编程风格来做到这一点:

Module[{lst = {}, numbers = {2, 3, 5, 7, 11, 13}},
  Do[AppendTo[lst, {i, numbers[[i]]}], {i, 1, Length@numbers}]; lst]

但这对于我看来是一个简单的操作来说相当冗长。例如,与此等效的 haskell 是

numbers = zip [1..] [2,3,5,7,11,13]

我不禁想到在Mathematica中有一种更简洁的“索引”数字列表的方法。

可能的答案

显然,除非我有 100 个“代表”,否则我不允许在灯泡熄灭后回答我自己的问题。所以我就把我的答案放在这里。让我知道我是否应该做一些与我所做的不同的事情。

好吧,问完这个问题后,我现在感觉有点傻。因为如果我将数学列表视为矩阵,我就可以转置它们。因此,我的问题的答案(也许不是最好的)如下:

Transpose[{Range@6, {2, 3, 5, 7, 11, 13}}]

编辑为适用于任意输入列表,我认为是这样的:

With[{lst={2, 3, 5, 7, 11, 13}},Transpose[{Range@Length@lst,lst}]]

会起作用。我能做得更好吗?

【问题讨论】:

  • 您的编辑看起来像是执行此操作的规范方式。
  • 谢谢,事实证明,我最近已经超过了 100 个“代表”。我现在应该将自己的答案复制到问题答案并从问题正文中删除吗?特别是当我的答案反映(完全正确!)给出的两个答案时。 (另外我推迟选择一个答案作为问题的“答案”,希望有更多的选择。如果转置方法是最好的,我应该批准哪个答案?下面给出的两个答案之一或我的复制下来?)
  • 这与所提出的问题无关,但我建议在几乎所有情况下都更喜欢Module(或With)而不是Block,并且只有在你真的使用Block时才使用知道它的作用,以及为什么需要它。
  • 不确定。我已经看到它是双向的。人们在问题框的底部或作为单独的答案进行总结和总结。您可能想阅读这个问题的答案:meta.stackexchange.com/q/2800/158668
  • 你当然不应该太早接受答案。它会阻止人们尝试自己的解决方案。通常几天就可以了。

标签: wolfram-mathematica


【解决方案1】:

要考虑的一件事是转换是否不会解包数据。这对于大型数据集很重要。

On["Packing"]

numbers = Developer`ToPackedArray@{2, 3, 5, 7, 11, 13};

这将解压

MapIndexed[{First[#2], #1} &, numbers]

这不会

Transpose[{Range[Length[#]], #}] &[numbers]

Off["Packing"]

【讨论】:

  • 我的问题没有具体解决性能问题。但既然您已经提到它:即使元素未打包(或只是不可打包),Transpose 会比 MapIndexed 快吗?
  • MapIndexed 的性能未来是否会有所提升,还是有一些不可避免的因素限制了它的效率?
  • @nixeagle 我一般无法回答。你必须尝试一下。
  • @Mr.Wizard 在这种情况下 MapIndexed 将不得不解包,这意味着评估者正在进入一个完全不同的级别,但尝试将其与编译版本进行比较 cf = Compile[{{numbers, _Integer, 1}}, MapIndexed[{First[#2], #1} &, numbers]] 看看效果如何。
【解决方案2】:

我会改用 MapIndexed

MapIndexed[{First[#2], #1} &, numbers]

【讨论】:

  • Transpose 方法的速度要快几个数量级。
【解决方案3】:

好吧,我的“解决方案”可能不如 cobbal 的解决方案聪明,但是当我用长数组测试它时,它更快(5 倍!)。 我只是在使用:

newList = Transpose[{Range[Length[numbers]], numbers}]

啊! ruebenko 在我写我的帖子期间发布了类似的答案。很抱歉这篇几乎是多余的帖子。好吧,也许它不是那么多余。我已经测试了我的解决方案有无打包,它可以在没有打包的情况下以最快的速度运行。

【讨论】:

  • 这与已在问题的编辑版本中发布的解决方案完全相同,该解决方案在您给出此答案前两个小时就已发布。我建议你删除这个答案。
  • 抱歉,我在发布此问题后无法识别问题的编辑版本(我刚刚识别了 ruebenko 的答案)。但是由于我首先在回答中提到了时间问题,所以我认为我不应该删除它。如果您和其他人认为它太多余,我不介意将其删除。无论如何,Nixeagle 也要求提供更好的解决方案。但到目前为止,我只知道更糟糕的一个(使用 for 循环……)。看看是否有比转置更快的东西会很有趣。
  • OP 使用前缀表示法(f@x 而不是 f[x]),但除此之外,两种解决方案都是相同的。您可能想查看这两种表示法的 FullForm。完全相同。
猜你喜欢
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
  • 2010-12-11
  • 2012-06-05
  • 1970-01-01
  • 2016-09-28
  • 2018-12-19
相关资源
最近更新 更多