从列表中删除空字符串

时间:2012-10-30 12:27:33

标签: python string list

我刚刚开始使用Python类,我真的需要一些帮助。请记住,如果你回答这个问题,我是新人。

我必须制作一个程序,它取特定列表中所有元素的平均值“l”。这本身就很简单;问题是老师要我们在做平均值之前删除列表中的任何空字符串。

所以当我收到列表[1,2,3,'',4]时,我希望函数忽略''的平均值,而只取其他4 / len(l)的平均值。谁能帮我这个?

可能是一个循环,一直将列表中的某个位置与''进行比较并从列表中删除它们?我试过了,但它没有用。

7 个答案:

答案 0 :(得分:13)

您可以使用列表推导来删除''的所有元素:

mylist = [1, 2, 3, '', 4]
mylist = [i for i in mylist if i != '']

然后,您可以通过将总和除以列表中元素的数量来计算平均值:

avg = sum(mylist)/len(mylist)

浮点平均值(假设python 2)

根据您的应用程序,您可能希望平均值为浮点数而不是int值。如果是这种情况,请先将其中一个值转换为浮点数:

avg = float(sum(mylist))/len(mylist)

或者你可以使用python 3的分区:

from __future__ import division
avg = sum(mylist)/len(mylist)

答案 1 :(得分:7)

您可以使用filter()

如果我们在Python 3中传递一个列表和一个filter(),那么

list会在Python 2中返回iterator。正如@PhilH所建议的那样,您可以在Python中使用itertools.ifilter() 2获取迭代器。

要在Python 3中获取列表作为输出,请使用list(filter(lambda x:x != '', lis))

In [29]: lis = [1, 2, 3, '', 4, 0]

In [30]: filter(lambda x:x != '', lis)
Out[30]: [1, 2, 3, 4, 0]

请注意,要过滤任何虚假值,您只​​需使用filter(None, ...)

>>> lis = [1, 2, 3, '', 4, 0]
>>> filter(None, lis)
[1, 2, 3, 4]

答案 2 :(得分:2)

其他答案向您展示如何创建一个删除了所需元素的新列表(这是在python中执行此操作的常用方法)。但是,在某些情况下,您希望在列表中进行操作 - 这是一种在列表中进行操作的方法:

while True:
    try:
        mylist.remove('')
    except ValueError:
        break

虽然我认为可以说你可以通过切片分配和列表理解来做到这一点:

mylist[:] = [i for i in mylist if i != '']

而且,有些人提出了有关内存使用和生成器奇迹的问题:

mylist[:] = (i for i in mylist if i != '')

也有效。

答案 3 :(得分:2)

itertools.ifilterfalse(lambda x: x=='', myList)

这使用迭代器,因此它不会创建列表的副本,并且应该在时间和内存方面更有效,使其对长列表更加健壮。

JonClements指出这意味着要分别跟踪长度,以便显示该过程:

def ave(anyOldIterator):
    elementCount = 0
    runningTotal = 0
    for element in anyOldIterator:
        runningTotal += element
        elementCount += 1
    return runningTotal/elementCount

甚至更好

def ave(anyOldIterator):
    idx = None
    runningTotal = 0
    for idx,element in enumerate(anyOldIterator):
        runningTotal += element
    return runningTotal/(idx+1)

减少

def ave(anyOldIterator):
    pieces = reduce(lambda x,y: (y[0],x[1]+y[1]), enumerate(anyOldIterator))
    return pieces[1]/(pieces[0]+1)

在平均范围(0,1000)上运行10000次的Timeit给出列表理解时间为0.9s,减少版本为0.16s。因此,在我们添加过滤之前,它已经快了5倍。

答案 4 :(得分:1)

您可以使用:

alist = ['',1,2]
new_alist = filter(None, alist)
new_alist_2 = filter(bool, alist)

结果:

new_alist = [1,2]
new_alist_2 = [1,2]

答案 5 :(得分:-1)

mylist = [1, 2, 3, '', 4]
newlist = []
for i in mylist:
    try:
        newlist.append(int(i))
    except ValueError:
        pass
avg = sum(newlist)/len(newlist)

答案 6 :(得分:-1)

''相当于False。如果我们过滤0 case(因为0等于False),我们可以使用list comprehension:

[x for x in a if x or x == 0]

或者,如果我们严格要过滤掉空字符串

[x for x in a if x != '']

这可能不是最快的方式。

编辑,添加了一些与其他解决方案相比较的替补结果(不是为了将自己与其他人比较,但我对最快的方法感到好奇)

ragsagar>
6.81217217445
pistache>
1.0873541832
cerealy>
1.07090902328
Matt>
1.40736508369
Ashwini Chaudhary>
2.04662489891
Phil H (just the generator) >
0.935978889465
Phil H with list() >
3.58926296234

我使用timeit()快速制作了脚本,我使用了[0,1,2,0,3,4,'',5,8,0,'',4]作为列表。我跑了多次测试,结果没有变化。

注意:我并不是试图以速度为标准将我的解决方案放在首位。我知道OP没有特别要求速度,但我很好奇,也许还有其他人。