python - "change"元组元素的优雅方法是什么?

标签 python tuples

<分区>

这极有可能是某物的副本,但我的 serach foo 使我失望了。

众所周知,元组是不可变的,因此您无法真正更改它们。然而,有时,将 (1, 2, "three") 更改为 (1, 2, 3) 的效果会派上用场,也许与 Haskell record update syntax. 类似您实际上不会更改原始元组,但您会得到一个元组,它只有一个(或多个)元素不同。

执行此操作的一种方法是:

elements = list(old_tuple)
elements[-1] = do_things_to(elements[-1])
new_tuple = tuple(elements)

我觉得将元组更改为列表有点违背了使用 old_tuple 的元组类型作为开头的目的:如果您使用的是列表,那么您就不会拥有为每个操作在内存中构建元组的一次性列表副本。

如果你只是改变元组的第三个元素,你也可以这样做:

def update_third_element(a, b, c, *others):
  c = do_things_to(c)
  return tuple(a, b, c, *others)

new_tuple = update_third_element(*old_tuple)

这会比朴素的方法更好地抵抗元组中元素数量的变化:

a, b, c, d, e, f, g, h, i, j = old_tuple
c = do_things_to(c)
new_tuple = (a, b, c, d, e, f, g, h, j, j) # whoops

...但如果您想更改的是最后一个元素,或者倒数第 n 个元素,则它不起作用。它还创建了一个丢弃列表(others)。它还会强制您命名所有元素,直到第 n 个。

有没有更好的办法?

最佳答案

我会使用 collections.namedtuple 代替:

>>> from collections import namedtuple

>>> class Foo(namedtuple("Foo", ["a", "b", "c"])):
        pass

>>> f = Foo(1, 2, 3)  # or Foo(a=1, b=2, c=3)
>>> f._replace(a = 5)
Foo(a=5, b=2, c=3)

namedtuple 还支持索引,因此您可以使用它们代替普通元组。

如果必须使用普通元组,只需使用辅助函数即可:

>>> def updated(tpl, i, val):
        return tpl[:i] + (val,) + tpl[i + 1:]

>>> tpl = (1, 2, 3)
>>> updated(tpl, 1, 5)
(1, 5, 3)

关于python - "change"元组元素的优雅方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23329525/

相关文章:

python - 匹配末尾正好 5 位数字的所有名称

python - 改进 Python 中点云空间感知中值滤波器的方法

python - Django 上传表单,附加字段导致错误

swift - 元组作为函数参数给出 "Unrecognized selector sent..."

list - 如何创建一个字典,将字符串映射到给定列表和元组的集合?

debugging - 调试时如何删除异常 "Predefined type ' ValueTuple` 2' must be a struct"?

Python - 来自特定文件夹的 Flask : Importing a . json 文件并根据 GET/POST 请求返回

python - 返回自定义时间戳

Scala - 如何在没有模式匹配的情况下对元组列表进行分组?

c++ - sizeof 可变参数模板(所有元素的 sizeof 之和)