【问题标题】:Is there a better way to use strip() on a list of strings? - python [duplicate]有没有更好的方法在字符串列表上使用 strip() ? -蟒蛇[重复]
【发布时间】:2012-08-24 08:22:51
【问题描述】:

现在我一直在尝试对字符串列表执行 strip(),我这样做了:

i = 0
for j in alist:
    alist[i] = j.strip()
    i+=1

有没有更好的方法?

【问题讨论】:

  • 支持随机匿名未注释的反对票。如果问题有问题,不告诉作者什么就投反对票是完全没有意义的。
  • 如果您想使用索引进行迭代,请执行for (i, value) in enumerate(alist)
  • 我添加了一个基准来比较这里描述的一些选项。

标签: python string list iterator strip


【解决方案1】:

我想你是说

a_list = [s.strip() for s in a_list]

使用生成器表达式可能是更好的方法,如下所示:

stripped_list = (s.strip() for s in a_list)

提供惰性求值的好处,因此strip 仅在需要剥离给定元素时运行。

如果您需要对列表的引用在当前范围之外保持完整,您可能需要使用列表切片语法。:

a_list[:] = [s.strip() for s in a_list]

对于对各种方法的速度感兴趣的评论者,看起来在 CPython 中生成器到切片的方法效率最低:

>>> from timeit import timeit as t
>>> t("""a[:]=(s.strip() for s in a)""", """a=[" %d " % s for s in range(10)]""")
4.35184121131897
>>> t("""a[:]=[s.strip() for s in a]""", """a=[" %d " % s for s in range(10)]""")
2.9129951000213623
>>> t("""a=[s.strip() for s in a]""", """a=[" %d " % s for s in range(10)]""")
2.47947096824646

【讨论】:

  • 为什么说“效率稍高一些”而不是分析和检查? BTW [:] 很有用,因为它会更改同一个列表,而不是将变量重新分配给新列表。
  • 它的效率较低,因为它必须复制 N 项而不是替换对列表的引用。您可能不需要或不想要的唯一“优势”是更改对任何对原始列表对象有另一个引用的人都是可见的。
  • 恕我直言,这不是pythonic。
  • 我已将其更改为生成器表达式,因为它更合适。
  • @Marcin 这可能是一种更合适的方法,但它对所提问题的回答不正确。我编辑了问题来描述这两个选项。
【解决方案2】:

你可以使用列表推导

stripped_list = [j.strip() for j in initial_list]

【讨论】:

  • 你认为列表推导能让代码运行得更快吗?还是更小??
  • 列表推导对于具有简单规则的可迭代对象非常有效。您可以根据复杂性使用地图和列表推导。但是,是的,它们确实提供了快速有效的实施
【解决方案3】:

这里发生了一些关于性能的有趣讨论,所以让我提供一个基准:

http://ideone.com/ldId8

noslice_map              : 0.0814900398254
slice_map                : 0.084676027298
noslice_comprehension    : 0.0927240848541
slice_comprehension      : 0.124806165695
iter_manual              : 0.133514881134
iter_enumerate           : 0.142778873444
iter_range               : 0.160353899002

所以:

  1. map(str.strip, my_list) 是最快的方式,只是比理解要快一点。
    • 如果您要应用单个函数(例如 str.split),请使用 mapitertools.imap
    • 如果有更复杂的表达式,请使用推导式
  2. 手动迭代是最慢的方式;一个合理的解释是它需要解释器做更多的工作,而高效的 C 运行时做的更少
  3. 继续分配像my_list[:] = map... 这样的结果,切片表示法只引入很小的开销,如果有多个对该列表的引用,可能会避免一些错误。
    • 了解改变列表和重新创建列表之间的区别。

【讨论】:

  • 你的意思是my_list = map(str.strip, list[:])?因为另一种方式给了我一个 NameError。
  • 我的意思是my_list[:] = map(str.strip, my_list)。查看链接下的代码。
【解决方案4】:

您可能不应该使用list 作为变量名,因为它是一种类型。无论如何:

list = map(str.strip, list) 

这会将函数str.strip 应用于list 中的每个元素,返回一个新列表,并将结果存储回list

【讨论】:

  • +1 就是这样。如果你想改变同一个列表实例而不是将变量绑定到一个新的实例(例如,不破坏对该列表的其他引用),请使用像@kojiro 所说的切片语法
  • map 是一个很好的选择的例子。 (当然,itertools.imap 可能更好也可能不会更好,例如在分配给切片时)。
  • @Kos 在这种情况下,基于迭代器的解决方案会更好(因为它避免了创建整个列表然后未被引用并等待垃圾回收)。
  • 不用担心,内存应该不是问题,因为我正在读取文件、搜索字符串并在找到字符串索引后将其丢弃。 =)
  • 在 python 2.x 的情况下,itertools.imap 更好,而不是使用 map 并将数据再次存储在列表中。在 python 3.x 中,map 将返回 iter。
猜你喜欢
  • 1970-01-01
  • 2017-09-18
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
相关资源
最近更新 更多