【问题标题】:list of lists in python, want to do arithmetic to each value in list, then append to listpython中的列表列表,想要对列表中的每个值进行算术运算,然后附加到列表
【发布时间】:2015-07-24 20:22:44
【问题描述】:

我有

expected_values =    
[[name, 4, 8, 3]
 [name, 2, 6, 9]
 [name, 3, 6, 2]]

我想做一些类似于将第二个值除以第一个值,然后将其乘以 3,然后将该值附加到列表末尾的操作。所以最终产品看起来像

expected_values = 
[[name, 4, 8, 3, 6]
 [name, 2, 6, 9, 9]
 [name, 3, 6, 2, 6]]

到目前为止我所拥有的是

for name in range(0,len(expected_values)):
    total = 0
    pa = expected_values[name][1]
    pa = int(pa)
    for s in range(0,len(expected_values)):
        singles = expected_values[s][2]
        singles = int(singles)
        total = total + ((singles/pa)*3)
    expected_values.append(total)

我在那里有 int(pa),因为它是从 CSV 文件导入的,显然它将所有内容都作为字符串导入,所以我必须将其转换为对其进行任何数学运算。

我对 Python 很陌生——这是作为一个暑期项目来学习这门语言的——而且我对列表中的列表索引有点不稳定,尤其是在这些循环中。

【问题讨论】:

  • 这不是一个重复的问题或任何东西,但请仔细阅读:stackoverflow.com/questions/19184335/…
  • 我原来是这样写的,看了别人的代码例子,但是这样写对我来说更直观。说“for name in expected_values:”之类的话让我有点困惑。我会在它实际工作后尝试重写它。不过谢谢你的链接,我会保存它。
  • 查看此行expected_values.append(total)。您正在追加到外部列表,但实际上您想追加到您正在处理的任何内部列表expected_values[name].append(total)
  • 当您说“乘以 3”时,您的意思是将结果乘以 3 还是乘以第三个元素?
  • 我的意思是将结果乘以 3,如示例中所示。抱歉打错了。

标签: python


【解决方案1】:

只需遍历添加sub[2]/sub[1] * 3 的列表,列表是可变的,append 是一个 inplace 操作,因此您每次追加时都在修改原始对象/列表,您不需要需要索引子列表或创建新列表:

expected_values =    [["name", 4, 8, 3], ["name", 2, 6, 9], ["name", 3, 6, 2]]

for sub in expected_values:
    sub.append(int(sub[2]) / int(sub[1]) * 3)

print(expected_values)

输出:

[['name', 4, 8, 3, 6], ['name', 2, 6, 9, 9], ['name', 3, 6, 2, 6]]

您只想确保 sub[2] 元素不是 0 以避免 ZeroDivisionError 并使用默认值或任何更可取的值:

for sub in expected_values:
    a,b = int(sub[1]), int(sub[2])
    sub.append(b / a * 3 if b else 0)

print(expected_values)

sub[2] 在您的第一个子列表中提取第三个元素,即8sub[1] 获得第二个元素,即4,您只需要相乘和追加。

如果您有实际的字符串数字,只需调用int(sub[2]) 等。根据您想要发生的情况,如果您使用 python2,您可能还希望将至少一个转换为浮点数,/ 将在 python 2 中使用整数。

【讨论】:

  • 谢谢,我几乎完全复制了你的第一个代码块,它可以工作。我不是很清楚它的逻辑,但我会研究它并尝试看看。
  • @jbf,你可以简单地迭代 python 中的列表,它不像 c 中使用 sizeof、索引等。列表在 python 中是可变的,这实际上非常重要,记住或者你可以最终会出现一些细微的错误,因此当您通过附加到列表末尾来更改列表时,您正在更改原始对象,您将引用 expected_values 列表中的每个子列表。
【解决方案2】:

除了这里的其他答案,也可以在一行中做到这一点:

name = "something"

expected_values =  [
                [name, 4, 8, 3],
                [name, 2, 6, 9],
                [name, 3, 6, 2]]

expected_values = [l + [(int(l[2])/int(l[1]))*3] for l in expected_values]

print(expected_values)

生产:

[['something', 4, 8, 3, 6], ['something', 2, 6, 9, 9], ['something', 3, 6, 2, 6]]

这个推导遍历外部列表。对于其中的每个子列表,都会将作为数学运算结果的一项的新列表添加到其中。

正如人们在 cmets 中指出的那样,这将具有稍低的性能(因为它会创建新列表)并且可能更难阅读,因此其他答案可能是更好的选择。但是,由于您(OP)是该语言的新手,我认为将列表理解用作替代方案可能对您有用。

【讨论】:

  • 这会创建一个新列表,它不会修改列表
  • @PadraicCunningham 是的,但最终结果是一样的。 OP 未指定无法创建新列表。
  • 创建新的列表和子列表和0(1)追加是不一样的,它们实际上也是使用追加然后将值追加到列表的末尾
  • 更不用说这是一个丑陋的列表理解。如果我在我维护的代码中看到了这一点,我可能会将它放在我的待办事项列表中以尽快重写它。
  • @PadraicCunningham 我同意。但 OP 也没有指定任何速度要求。我只是建议一种替代方法,并且由于他/她显然是该语言的新手,我认为这将是一个介绍理解的好机会。我同意两位炼金术士的观点,尽管您的答案更简洁。
猜你喜欢
  • 2019-03-29
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多