数组列表的平均值,存储为Python列表中的字符串

时间:2014-01-20 09:12:06

标签: python list-comprehension

我想计算python中几个列表的平均值。这些列表包含数字作为字符串。空字符串不为零,表示缺少值。

我能想到的最好的就是这个。是否更优雅,简洁&有效的写作方式?

num    = ['1', '2', '', '6']
total  = sum([int(n) if n else 0 for n in num])
length = sum([1 if n else 0 for n in num])
ave    = float(total)/length if length > 0 else '-'

P.S。我正在使用Python 2.7.x,但欢迎使用Python 3.x的配方

5 个答案:

答案 0 :(得分:4)

num = ['1', '2', '', '6']
L = [int(n) for n in num if n]
ave = sum(L)/float(len(L)) if L else '-'

num = ['1', '2', '', '6']
L = [float(n) for n in num if n]
avg = sum(L)/len(L) if L else '-'

答案 1 :(得分:3)

在Python 3.4中使用statistics 库:

from statistics import mean
num = ['1', '2', '', '6']
ave = mean(int(n) if n else 0 for n in num)

答案 2 :(得分:1)

您可以丢弃方括号。 sum也接受生成器表达式:

total  = sum(int(n) if n else 0 for n in num)
length = sum(1 if n else 0 for n in num)

由于生成器仅在需要时生成值,因此可以节省在内存中存储列表的昂贵成本。特别是如果你正在处理更大的数据。

答案 3 :(得分:1)

这是关于OP解决方案与aIKid解决方案与gnibbler解决方案的一些时间安排,使用1..9(加上空字符串)和10个试验中的100,000个数字列表:

import timeit

setup = '''
from __main__ import f1, f2, f3, f4
import random


random.seed(0)
choices = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '']
num = [random.choice(choices) for _ in range(10**5)]
'''

def f1(num): # OP
    total  = sum([int(n) if n else 0 for n in num])
    length = sum([1 if n else 0 for n in num])
    ave    = float(total)/length if length > 0 else '-'
    return ave

def f2(num): # aIKid
    total = sum(int(n) if n else 0 for n in num)
    length = sum(1 if n else 0 for n in num)
    ave = float(total)/length if length > 0 else '-'
    return ave

def f3(num): # gnibbler 1
    L = [int(n) for n in num if n]
    ave = sum(L)/float(len(L)) if L else '-'
    return ave

def f4(num): # gnibbler 2
    L = [float(n) for n in num if n]
    ave = sum(L)/float(len(L)) if L else '-'
    return ave

number = 10
things = ['f1(num)', 'f2(num)', 'f3(num)', 'f4(num)']
for thing in things:
    print(thing, timeit.timeit(thing, setup=setup, number=number))

结果:

f1(num) 1.8177659461490339 # OP
f2(num) 2.0769015213241513 # aIKid
f3(num) 1.6350571199344595 # gnibbler 1
f4(num) 0.807052779158564  # gnibbler 2

看起来使用float的gnibbler解决方案是最快的。

答案 4 :(得分:0)

一种不同的方法

num    = ['1', '2', '', '6']
total = reduce(lambda acc, x: float(acc) + (float(x) if x else 0),num,0)
length = reduce(lambda acc, x: float(acc) + (1 if x else 0),num,0)
average = (',',total/length)[length > 0]