首页 文章

从字符串列表中删除空字符串

提问于
浏览
519

我想从python中的字符串列表中删除所有空字符串 .

我的想法是这样的:

while '' in str_list:
    str_list.remove('')

有没有更多的pythonic方式来做到这一点?

14 回答

  • 5

    我会用filter

    str_list = filter(None, str_list) # fastest
    str_list = filter(bool, str_list) # fastest
    str_list = filter(len, str_list)  # a bit slower
    str_list = filter(lambda item: item, str_list) # slower than list comprehension
    

    Python 3从 filter 返回一个迭代器,因此应该包含在对 list() 的调用中

    str_list = list(filter(None, str_list)) # fastest
    

    (等等 . )

    测试:

    >>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
    2.4797441959381104
    >>> timeit('filter(bool, str_list)', 'str_list=["a"]*1000', number=100000)
    2.4788150787353516
    >>> timeit('filter(len, str_list)', 'str_list=["a"]*1000', number=100000)
    5.2126238346099854
    >>> timeit('[x for x in str_list if x]', 'str_list=["a"]*1000', number=100000)
    13.354584932327271
    >>> timeit('filter(lambda item: item, str_list)', 'str_list=["a"]*1000', number=100000)
    17.427681922912598
    
  • -3

    List comprehensions

    strings = ["first", "", "second"]
    [x for x in strings if x]
    

    输出: ['first', 'second']

    编辑:按建议缩短

  • 6

    filter实际上有一个特殊的选项:

    filter(None, sequence)
    

    它将过滤掉所有评估为False的元素 . 不需要在这里使用实际的可调用对象,如bool,len等 .

    它和 Map 一样快(bool,......)

  • 9
    >>> lstr = ['hello', '', ' ', 'world', ' ']
    >>> lstr
    ['hello', '', ' ', 'world', ' ']
    
    >>> ' '.join(lstr).split()
    ['hello', 'world']
    
    >>> filter(None, lstr)
    ['hello', ' ', 'world', ' ']
    

    比较时间

    >>> from timeit import timeit
    >>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
    4.226747989654541
    >>> timeit('filter(None, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
    3.0278358459472656
    

    请注意 filter(None, lstr) 不会删除空格 ' ' 的空字符串,它只会删除 ''' '.join(lstr).split() 同时删除它们 .

    要删除空白字符串 filter() ,需要花费更多时间:

    >>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
    18.101892948150635
    
  • -2

    而不是if,我会使用X!=''来消除空字符串 . 像这样:

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

    这将在列表中保留None数据类型 . 此外,如果您的列表有整数,0是其中之一,它也将被保留 .

    例如,

    str_list = [None, '', 0, "Hi", '', "Hello"]
    [x for x in str_list if x != '']
    [None, 0, "Hi", "Hello"]
    
  • 177

    来自@ Ib33X的回复太棒了 . 如果要删除每个空字符串,请在剥离后删除 . 你也需要使用strip方法 . 否则,如果它有空格,它也将返回空字符串 . 就像,“”对于那个答案也是有效的 . 所以,可以实现 .

    strings = ["first", "", "second ", " "]
    [x.strip() for x in strings if x.strip()]
    

    答案是 ["first", "second"] .
    如果你想使用 filter 方法,你可以这样做
    list(filter(lambda item: item.strip(), strings)) . 这给出了相同的结果 .

  • 17

    使用 filter

    newlist=filter(lambda x: len(x)>0, oldlist)
    

    指出使用过滤器的缺点是它比替代品慢;另外, lambda 通常很昂贵 .

    或者你可以选择最简单,最迭代的方法:

    # I am assuming listtext is the original list containing (possibly) empty items
    for item in listtext:
        if item:
            newlist.append(str(item))
    # You can remove str() based on the content of your original list
    

    这是最直观的方法,并且在适当的时间内完成 .

  • 2

    根据列表的大小,如果使用list.remove()而不是创建新列表,则效率最高:

    l = ["1", "", "3", ""]
    
    while True:
      try:
        l.remove("")
      except ValueError:
        break
    

    这样做的好处是不创建新列表,但每次都必须从头开始搜索,尽管不像上面提到的那样使用 while '' in l ,但每次出现时只需要搜索一次 '' (肯定有办法保留最好的两种方法,但它更复杂) .

  • 58

    Aziz Alto filter(None, lstr) 报告不会删除空字符串 ' ' ,但如果您确定lstr只包含字符串,则可以使用 filter(str.strip, lstr)

    >>> lstr = ['hello', '', ' ', 'world', ' ']
    >>> lstr
    ['hello', '', ' ', 'world', ' ']
    >>> ' '.join(lstr).split()
    ['hello', 'world']
    >>> filter(str.strip, lstr)
    ['hello', 'world']
    

    比较我的电脑上的时间

    >>> from timeit import timeit
    >>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
    3.356455087661743
    >>> timeit('filter(str.strip, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
    5.276503801345825
    

    使用空格 ' ' 删除 '' 和空字符串的最快解决方案仍为 ' '.join(lstr).split() .

    如评论中所述,如果您的字符串包含空格,情况就不同了 .

    >>> lstr = ['hello', '', ' ', 'world', '    ', 'see you']
    >>> lstr
    ['hello', '', ' ', 'world', '    ', 'see you']
    >>> ' '.join(lstr).split()
    ['hello', 'world', 'see', 'you']
    >>> filter(str.strip, lstr)
    ['hello', 'world', 'see you']
    

    您可以看到 filter(str.strip, lstr) 保留带有空格的字符串,但 ' '.join(lstr).split() 将拆分此字符串 .

  • 875

    请记住,如果您想保留 white spaces within a string ,可以使用某些方法无意中删除它们 . 如果你有这个清单

    ['你好世界','','','你好']你可能想要什么['你好世界','你好']

    首先修剪列表以将任何类型的空格转换为空字符串:

    space_to_empty = [x.strip() for x in _text_list]
    

    然后从列表中删除空字符串

    space_clean_list = [x for x in space_to_empty if x]
    
  • 0

    剥离后消除空箱:

    slist = map(lambda s: s and s.strip(), slist)
    slist = filter(None, slist)
    

    一些PRO:

    • 懒惰,基于生成器,以节省内存;

    • 代码的可理解性;

    • 快速,有选择地使用内置和理解 .

    def f1(slist):
        slist = [s and s.strip() for s in slist]
        return list(filter(None, slist))
    
    def f2(slist):
        slist = [s and s.strip() for s in slist]
        return [s for s in slist if s]
    
    
    def f3(slist):
        slist = map(lambda s: s and s.strip(), slist)
        return list(filter(None, slist))
    
    def f4(slist):
        slist = map(lambda s: s and s.strip(), slist)
        return [s for s in slist if s]
    
    %timeit f1(words)
    10000 loops, best of 3: 106 µs per loop
    
    %timeit f2(words)
    10000 loops, best of 3: 126 µs per loop
    
    %timeit f3(words)
    10000 loops, best of 3: 165 µs per loop
    
    %timeit f4(words)
    10000 loops, best of 3: 169 µs per loop
    
  • 4
    str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']
    
    for item in str_list:
        if len(item) < 1:  
            str_list.remove(item)
    

    简短又甜蜜 .

  • -3

    循环遍历现有字符串列表然后检查空字符串,如果它不为空,则填充具有非空值的新字符串列表,然后用新字符串列表替换旧字符串列表

  • 9

    filter(None, str) 不会删除空格' '的空字符串,它只会删除'' and '' .

    join(str).split() 删除两者 . 但是如果你的列表元素有空格那么它也会改变你的列表元素,因为它首先加入你列表的所有元素然后用空格来拼写它们所以你应该使用: -

    str = ['hello', '', ' ', 'world', ' ']
    print filter(lambda x:x != '', filter(lambda x:x != ' ', str))
    

    它会删除这两个并且不会影响你的元素也像: -

    str = ['hello', '', ' ', 'world ram', ' ']
    print  ' '.join(lstr).split()
    print filter(lambda x:x != '', filter(lambda x:x != ' ', lstr))
    

    输出: -

    ['hello','world','ram'] <-------------- ' '.join(lstr).split() 的输出
    ['hello','world ram']

相关问题