Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 列表理解:优雅地去除列表中的空元素_Python_Scrapy_List Comprehension_Strip - Fatal编程技术网

Python 列表理解:优雅地去除列表中的空元素

Python 列表理解:优雅地去除列表中的空元素,python,scrapy,list-comprehension,strip,Python,Scrapy,List Comprehension,Strip,我正在使用Scrapy lib。我经常得到带有“\t”和“\n”的列表 我试图使用列表理解来剥离和删除结果中的空元素,但最终仍然是空元素 有人能解释一下解释器是如何处理代码的吗?它似乎是在检查空元素,然后将元素剥离并重新插入列表中 提前谢谢你 # input char_list = ['', ' a','b', '\t'] print char_list char_list = [x.strip() for x in char_list if x!=''] print char_list

我正在使用Scrapy lib。我经常得到带有“\t”和“\n”的列表

我试图使用列表理解来剥离和删除结果中的空元素,但最终仍然是空元素

有人能解释一下解释器是如何处理代码的吗?它似乎是在检查空元素,然后将元素剥离并重新插入列表中

提前谢谢你

# input
char_list = ['', '    a','b', '\t']
print char_list
char_list = [x.strip() for x in char_list if x!='']
print char_list

# output
['', '    a', 'b', '\t']
['a', 'b', '']

#DESIRED output
['', '    a', 'b', '\t']
['a', 'b']

你想要的是删除无用的字符串。x=“”无法删除“\t”。

通常在这种情况下,我会将其更改为两个步骤。。。在第一步中,我进行可能非常昂贵的处理。在第二步中,我进行过滤。第一步可以使用生成器表达式完成,以避免不必要的列表:

char_list_stripped = (x.strip() for x in char_list)
char_list = [x for x in char_list_stripped if x]

在这种情况下,它可以使您避免调用
x.strip
实际需要调用次数的两倍(如果您要将所有调用都打包到一个单独的理解中)。这可能不会带来巨大的节约(您可能不会注意到速度差异)。但在更一般的情况下,它可能会产生显著的差异,这取决于处理过程实际需要的工作量。

双重理解将比调用两次strip()的单一理解更有效


在spider中硬编码这样的东西不是一个好的做法。看看Scrapy和输入/输出处理器。 在REPL中尝试以下操作:

from  scrapy.contrib.loader.processor import MapCompose

def compact(s):
    """ returns None if string is empty, otherwise string itself """
    return s if s else None

char_list = ['', '    a','b', '\t']
MapCompose(unicode.strip, compact)(char_list)
=> ['a', 'b']
将给定函数按顺序应用于每个项,每个函数将一个项作为参数,不包括将来处理中的任何项

在items.py中使用此方法的最简单方法是:

# -*- coding: utf-8 -*-
import scrapy
from  scrapy.contrib.loader.processor import MapCompose

def compact(s):
    return s if s else None

class MyItem(scrapy.Item):
    my_field = scrapy.Field(
        input_processor=MapCompose(unicode.strip, compact)
    )
在您的爬行器的parse_my_items回调中:

from scrapy.contrib.loader import ItemLoader
from myproject.items import MyItem

il = ItemLoader(item=MyItem())
il.add_value('my_field', char_list)
my_item = il.load_item()
yield my_item
#=> {'my_field': [u'a', u'b']}

希望这有帮助

mgilsons生成器更高效,但仍然可以是单步
char\u list=[x代表x in(x.strip()代表x代表x in char\u list),如果x]
感谢您的响应。为什么要执行strip()函数两次?只想给出您想要的第一个strip给出所需的strip,第二个strip检查条件,因此第一个strip只会运行第二个strip。如果第二个strip为true,那么真正的问题是为什么要执行
strip
函数一次,这就是为什么您的代码不能正常工作的原因。谢谢你的解释!
from  scrapy.contrib.loader.processor import MapCompose

def compact(s):
    """ returns None if string is empty, otherwise string itself """
    return s if s else None

char_list = ['', '    a','b', '\t']
MapCompose(unicode.strip, compact)(char_list)
=> ['a', 'b']
# -*- coding: utf-8 -*-
import scrapy
from  scrapy.contrib.loader.processor import MapCompose

def compact(s):
    return s if s else None

class MyItem(scrapy.Item):
    my_field = scrapy.Field(
        input_processor=MapCompose(unicode.strip, compact)
    )
from scrapy.contrib.loader import ItemLoader
from myproject.items import MyItem

il = ItemLoader(item=MyItem())
il.add_value('my_field', char_list)
my_item = il.load_item()
yield my_item
#=> {'my_field': [u'a', u'b']}