8

是否有任何内置函数允许在 Python 3 中对元组进行元素操作?如果不是,执行这些操作的“pythonic”方式是什么?

示例:我想获取 和 之间的百分比差异a并将b它们与某个阈值进行比较th

>>> a = (1, 2, 4)
>>> b = (1.1, 2.1, 4.1)
>>> # compute pd = 100*abs(a-b)/a = (10.0, 5.0, 2.5)
>>> th = 3
>>> # test threshold: pd < th => (False, False, True)
4

6 回答 6

11

没有内置方法,但有一个非常简单的方法:

[f(aItem, bItem) for aItem, bItem in zip(a, b)]

. . . f您要按元素应用的功能在哪里。对于您的情况:

[100*abs(aItem - bItem)/aItem < 3 for aItem, bItem in zip(a, b)]

如果您发现自己经常这样做,尤其是对于长元组,您可能需要查看Numpy,它提供了一个功能齐全的向量运算系统,其中许多常见的向量函数(基本运算、三角函数等)按元素应用。

于 2012-08-24T16:35:19.150 回答
6

地图功能

>>> a = (1, 2, 4)
>>> b = (1.1, 2.1, 4.1)
>>> map(lambda a,b: 100*abs(a-b)/a < 3, a, b)
[False, False, True]

编辑

当然,您可以使用列表推导而不是地图,例如 BrenBarn 所做的 http://docs.python.org/tutorial/datastructures.html#nested-list-comprehensions

EDIT 2 zip 已删除,感谢 DSM 指出不需要 zip

于 2012-08-24T16:35:56.850 回答
5

为什么不使用 NumPy?

import numpy as np
a = np.array([1,2,4])
b = np.array([1.1, 2.1, 4.1])

pd = 100*abs(a-b)/a # result: array([ 10. ,   5. ,   2.5])
th = 3
pd < th # result: array([False, False,  True], dtype=bool)
于 2012-08-24T16:48:58.273 回答
1

我不知道这样的操作,也许 Python 的一些函数式编程特性会起作用(map?reduce?),尽管将列表理解(或如果不需要列表的生成器)放在一起相对简单:

[100*abs(j-b[i])/j < 3 for i,j in enumerate(a)]
[False, False, True]

感谢@delnan 为原始、更明确/详细的版本指出了一个非常好的简化:

[True if 100*abs(j-b[i])/j < 3 else False for i,j in enumerate(a)]
于 2012-08-24T16:32:57.910 回答
0

我会说 Pythonic 的方式是列表理解:

何时a = (1, 2, 4)b = (1.1, 2.1, 4.1)

然后,在一行中:

TEST = [100*abs(a[i]-b[i])/a[i] > th for i in range(len(A))]
于 2012-08-24T16:35:42.643 回答
0
def pctError(observed, expected):
    return (observed-expected)/expected * 100.0

a = (1, 2, 4)
b = (1.1, 2.1, 4.1)
th = 3

pctErrors = map(lambda t:pctError(*t), zip(a,b))
# returns [-9.091, -4.76, -2.44]

map(lambda x: x < th, pctErrors)
[x < th for x in pctErrors]
# both return [True, True, True]

# or if you always need absolute % errors
map(lambda x: abs(x) < th, pctErrors)
[abs(x) < th for x in pctErrors]
# both return [False, False, True]
于 2012-08-24T16:43:18.360 回答