2

我有这个清单:

dCF3v=[[(1.90689635276794, -44704.76171875)],
       [(1.90689635276794, -44705.76171875)],
       [(1.90689635276794, -44706.76171875)],
       [(1.90689635276794, -44707.76171875)]
      ]

我想比较每个元组的第二个元素并找到绝对最大值:

-44707.76171875

我的代码如下所示:

CF3=0
for x in dCF3v:
    if abs(x[1])>abs(CF3):
        CF3=x[1]
4

6 回答 6

4

您有一个包含包含元组的列表的列表。所以,你可能想要abs(x[0][1]).
然后你的命令可以简单地是:

max(abs(x[0][1]) for x in dCF3v)

更重要的是,您可能实际上想要将数据结构更改为包含元组的列表:

dCF3v = [x[0] for x in dCF3v]

然后看起来像:

max(abs(x[0]) for x in dCF3v)

或者,如果您希望返回整个元组而不仅仅是第二个元素:

max(dCF3v,key=lambda x:abs(x[0]))
于 2013-05-02T14:47:11.637 回答
1

我的尝试是帮助您获得最快、最易读的版本。为此,我的建议是首先创建一个生成器,它将产生您想要的值。然后在这个生成器上执行内置max()函数。这更快/更有效的原因几乎与将生成器嵌入max()函数中相同,在 Python 中仅使用局部变量比使用全局变量更快,一旦max()函数不必像x[0][1]更快那样查找索引。

vals = (abs(x[0][1]) for x in dCF3v)
print max(vals)

定时:

我使用以下代码计算了我的答案和mgilsons答案之间的差异:

import time
dCF3v = [[(1.90689635276794, -44706.76171875)], [(1.90689635276794, -44706.76171875)], [(1.90689635276794, -44706.76171875)], [(1.90689635276794, -44706.76171875)]]

def method_inbar(l):
    vals = (abs(x[0][1]) for x in l)
    max(vals)

def method_mgilson(l):
    max(abs(x[0][1]) for x in l)

def timer(multiplier=[1,10,100,1000]):
    for m in multiplier:
        print "timing the speed using multiplier: %s" % m
        now = time.time()
        for i in range(100000):
            method_inbar(dCF3v*m)
        print "inbar's method: %r" % (time.time() - now)
        now = time.time()
        for i in range(100000):
            method_mgilson(dCF3v*m)
        print "mgilson's method: %r" % (time.time() - now)

timer()

这将每次在更大的数据集上运行测试:

>>> 
timing the speed using multiplier: 1
inbar's method: 0.18899989128112793
mgilson's method: 0.192000150680542
timing the speed using multiplier: 10
inbar's method: 0.8540000915527344
mgilson's method: 0.8229999542236328
timing the speed using multiplier: 100
inbar's method: 7.287999868392944
mgilson's method: 7.45199990272522
timing the speed using multiplier: 1000
inbar's method: 71.42099976539612
mgilson's method: 77.18499994277954

如您所见,在大量数据上。它更快。唯一的原因是速度较慢是因为启动 vals 需要时间,而且由于我多次运行这些函数,它似乎慢得多,但如果你只运行一次,那么对于较小的数据集你应该没有什么区别,但是对于大型数据集,您应该会感觉到很大的差异。(只有 1000 次的几秒钟)

于 2013-05-02T15:02:10.303 回答
1
max(map(lambda t: abs(t[1]),chain(*dCF3v))))

或者

max(map(lambda t: abs(t[1]),chain.from_iterable(dCF3v)))

演练:

print(list(chain(*dCF3v)))
print([abs(t[1]) for t in list(chain(*dCF3v))])

产生:

>>> 
[(1.90689635276794, -44706.76171875), (1.90689635276794, -44706.76171875), (1.90689635276794, -44706.76171875), (1.90689635276794, -44706.76171875)]
[44706.76171875, 44706.76171875, 44706.76171875, 44706.76171875]
于 2013-05-02T14:53:27.807 回答
1

为此使用该max功能,这可能是最直接的解决方案:

max(dCF3v, key=lambda x: abs(x[0][1]))[0][1]
=> -44706.76171875
于 2013-05-02T14:53:31.663 回答
1

这是因为你有一个元组列表,而不仅仅是一个元组列表。请考虑以下代码,或者您可以将您的代码更改x[1]x[0][1].

>>> max(abs(x[0][1]) for x in dCF3v)
44706.76171875

这使用了一个内置函数,该函数max在可迭代对象中选择最大元素,并使用生成器将 abs 函数映射到每个元素,这将保持快速和内存效率。

于 2013-05-02T14:50:19.993 回答
1

简单地做

dCF3v=[[(1.90689635276794, -44706.76171875)],
       [(1.90689635276794, -44706.76171875)],
       [(1.90689635276794, -44706.76171875)],
       [(1.90689635276794, -44706.76171875)]
      ]

M = max([x[0][1] for x in dCF3v])
于 2013-05-02T15:03:05.690 回答