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

2024-12-12 08:41:00
admin
原创
134
摘要:问题描述:我想从 python 中的字符串列表中删除所有空字符串。我的想法是这样的:while '' in str_list: str_list.remove('') 有没有更符合 Python 风格的方法来做到这一点?解决方案 1:我会用filter:str_list = filter(None, ...

问题描述:

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

我的想法是这样的:

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

有没有更符合 Python 风格的方法来做到这一点?


解决方案 1:

我会用filter

str_list = filter(None, str_list)
str_list = filter(bool, str_list)
str_list = filter(len, str_list)
str_list = filter(lambda item: item, str_list)

Python 3 从 返回一个迭代器filter,因此应该包装在对list()

str_list = list(filter(None, str_list))

解决方案 2:

使用列表推导是最 Python 的方式:

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

如果必须就地修改列表,因为还有其他引用必须看到更新的数据,那么使用切片分配:

strings[:] = [x for x in strings if x]

解决方案 3:

过滤器实际上对此有一个特殊的选项:

filter(None, sequence)

它将过滤掉所有结果为 False 的元素。这里无需使用实际的可调用函数,例如 bool、len 等。

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

解决方案 4:

>>> 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

解决方案 5:

总结最佳答案:

  1. 无需剥离即可消除空瓶:


也就是说,所有空格字符串都被保留:

slist = list(filter(None, slist))

优点:

  • 最簡單;

  • 最快(见下面的基准)。

  1. 清除清废后的空瓶...


2.a...当字符串不包含单词之间的空格时:

slist = ' '.join(slist).split()

优点:

  • 小码

  • 速度快(但由于内存问题,处理大数据集时速度不是最快的,与@paolo-melchiorre 的结果相反)

2.b...当字符串包含单词之间的空格时?

slist = list(filter(str.strip, slist))

优点:

  • 最快;

  • 代码的可理解性。

2018 年机器上的基准:

## Build test-data
#
import random, string
nwords = 10000
maxlen = 30
null_ratio = 0.1
rnd = random.Random(0)                  # deterministic results
words = [' ' * rnd.randint(0, maxlen)
         if rnd.random() > (1 - null_ratio)
         else
         ''.join(random.choices(string.ascii_letters, k=rnd.randint(0, maxlen)))
         for _i in range(nwords)
        ]

## Test functions
#
def nostrip_filter(slist):
    return list(filter(None, slist))

def nostrip_comprehension(slist):
    return [s for s in slist if s]

def strip_filter(slist):
    return list(filter(str.strip, slist))

def strip_filter_map(slist): 
    return list(filter(None, map(str.strip, slist))) 

def strip_filter_comprehension(slist):  # waste memory
    return list(filter(None, [s.strip() for s in slist]))

def strip_filter_generator(slist):
    return list(filter(None, (s.strip() for s in slist)))

def strip_join_split(slist):  # words without(!) spaces
    return ' '.join(slist).split()

## Benchmarks
#
%timeit nostrip_filter(words)
142 µs ± 16.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit nostrip_comprehension(words)
263 µs ± 19.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit strip_filter(words)
653 µs ± 37.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit strip_filter_map(words)
642 µs ± 36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit strip_filter_comprehension(words)
693 µs ± 42.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit strip_filter_generator(words)
750 µs ± 28.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit strip_join_split(words)
796 µs ± 103 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

解决方案 6:

@Ib33X 的回复很棒。如果您想在删除后删除每个空字符串。您也需要使用 strip 方法。否则,如果字符串中有空格,它也会返回空字符串。例如,“ ”对于该答案也有效。因此,可以通过以下方式实现。

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

答案是["first", "second"]

如果您想使用filter方法,可以这样做

list(filter(lambda item: item.strip(), strings))。这会产生相同的结果。

解决方案 7:

我将使用 if X != '' 而不是 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"]

解决方案 8:

你可以使用类似这样的东西

test_list = [i for i in test_list if i]

其中 test_list 是要从中删除空元素的列表。

解决方案 9:

根据列表的大小,使用 list.remove() 而不是创建新列表可能会最有效:

l = ["1", "", "3", ""]

while True:
  try:
    l.remove("")
  except ValueError:
    break

这样做的好处是不需要创建新的列表,但缺点是每次都必须从头开始搜索,尽管与while '' in l上面建议的使用方法不同,它只需要在每次出现时搜索一次''(当然有一种方法可以兼具两种方法的优点,但它更复杂)。

解决方案 10:

据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()会拆分这些字符串。

解决方案 11:

请记住,如果您想保留字符串中的空格,您可能会使用某些方法无意中删除它们。如果您有此列表

['hello world', ' ', '', 'hello'] 你可能想要什么 ['hello world','hello']

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

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

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

space_clean_list = [x for x in space_to_empty if x]

解决方案 12:

使用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

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

解决方案 13:

使用正则表达式和过滤器进行匹配

lstr = ['hello', '', ' ', 'world', ' ']
r=re.compile('^[A-Za-z0-9]+')
results=list(filter(r.match,lstr))
print(results)

解决方案 14:

这对我有用。我也有 nan 值,因为我是从 pandas dataframe 列值创建此列表的。

[x for x in a if pd.notna(x) and x.strip()]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用