简体   繁体   English

从列表中删除空字符串

[英]Remove empty string from list

I just started Python classes and I'm really in need of some help. 我刚刚开始使用Python类,我真的需要一些帮助。 Please keep in mind that I'm new if you're answering this. 请记住,如果你回答这个问题,我是新手。

I have to make a program that takes the average of all the elements in a certain list "l". 我必须制作一个程序,它取特定列表中所有元素的平均值“l”。 That is a pretty easy function by itself; 这本身就很简单; the problem is that the teacher wants us to remove any empty string present in the list before doing the average. 问题是老师要我们在做平均值之前删除列表中的任何空字符串。

So when I receive the list [1,2,3,'',4] I want the function to ignore the '' for the average, and just take the average of the other 4/len(l). 因此,当我收到列表[1,2,3,'',4]我希望函数忽略''作为平均值,并且只取其他4 / len(l)的平均值。 Can anyone help me with this? 谁能帮我这个?

Maybe a cycle that keeps comparing a certain position from the list with the '' and removes those from the list? 也许是一个循环,不断将列表中的某个位置与''并从列表中删除它们? I've tried that but it's not working. 我试过了,但它不起作用。

You can use a list comprehension to remove all elements that are '' : 您可以使用列表推导来删除所有''元素:

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

Then you can calculate the average by taking the sum and dividing it by the number of elements in the list: 然后,您可以通过将总和除以列表中元素的数量来计算平均值:

avg = sum(mylist)/len(mylist)

Floating Point Average (Assuming python 2) 浮点平均值(假设python 2)

Depending on your application you may want your average to be a float and not an int. 根据您的应用程序,您可能希望平均值为浮点数而不是int值。 If that is the case, cast one of these values to a float first: 如果是这种情况,请先将其中一个值转换为float:

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

Alternatively you can use python 3's division: 或者你可以使用python 3的部门:

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

You can use filter() : 你可以使用filter()

filter() returns a list in Python 2 if we pass it a list and an iterator in Python 3. As suggested by @PhilH you can use itertools.ifilter() in Python 2 to get an iterator. 如果我们在Python 3中传递一个列表和一个iteratorfilter()在Python 2中返回一个list 。正如@PhilH所建议的,您可以在Python 2中使用itertools.ifilter()来获取迭代器。

To get a list as output in Python 3 use list(filter(lambda x:x != '', lis)) 要在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]

Note to filter any falsy value you can simply use filter(None, ...) : 注意要过滤任何虚假值,您只​​需使用filter(None, ...)

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

The other answers show you how to create a new list with the desired element removed (which is the usual way to do this in python). 其他答案向您展示如何创建一个删除了所需元素的新列表(这是在python中执行此操作的常用方法)。 However, there are occasions where you want to operate on a list in place -- Here's a way to do it operating on the list in place: 但是,在某些情况下,您希望在列表中进行操作 - 这是一种在列表中操作的方法:

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

Although I suppose it could be argued that you could do this with slice assignment and a list comprehension: 虽然我认为可以说你可以通过切片分配和列表理解来做到这一点:

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

And, as some have raised issues about memory usage and the wonders of generators: 并且,正如一些人提出了关于内存使用和生成器奇迹的问题:

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

works too. 也有效。

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

This uses iterators, so it doesn't create copies of the list and should be more efficient both in time and memory, making it robust for long lists. 这使用迭代器,因此它不会创建列表的副本,并且应该在时间和内存方面更高效,使其对长列表更加健壮。

JonClements points out that this means keeping track of the length separately, so to show that process: JonClements指出这意味着要分别跟踪长度,以便显示该过程:

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

Or even better 甚至更好

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

Reduce: 降低:

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

Timeit on the average of range(0,1000) run 10000 times gives the list comprehension a time of 0.9s and the reduce version 0.16s. 在平均范围(0,1000)运行10000次的时间上给出列表理解时间为0.9s,减少版本为0.16s。 So it's already 5x faster before we add in filtering. 因此,在我们添加过滤之前,它已经快了5倍。

You can use: 您可以使用:

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

Result: 结果:

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

'' is equivalent to False. ''相当于False。 If we filter the 0 case out (because 0 is equivalent to False), we can use list comprehension : 如果我们过滤0个案例(因为0等于False),我们可以使用列表理解:

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

Or if we strictly want to filter out empty strings : 或者,如果我们严格要过滤掉空字符串

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

This may not be the fastest way. 这可能不是最快的方式。

Edit , added some bench results comparing with the other solutions (not for the sake of comparing myself to others, but I was curious too of what method was the fastest) 编辑 ,添加了一些与其他解决方案相比较的替补结果(不是为了将自己与其他解决方案进行比较,但我对最快的方法感到好奇)

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

I made the script quickly, using timeit(), I used [0,1,2,0,3,4,'',5,8,0,'',4] as the list. 我使用timeit()快速制作了脚本,我使用了[0,1,2,0,3,4,'',5,8,0,'',4]作为列表。 I ran multiple tests, results did not vary. 我跑了多次测试,结果没有变化。

NOTE: I'm not trying to put my solution on top using speed as a criteria. 注意:我不是试图使用速度作为标准将我的解决方案放在首位。 I know OP didn't specifically ask for speed, but I was curious and maybe some other are. 我知道OP没有特别要求速度,但我很好奇,也许还有其他的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM