我试图从字符串中删除所有提及的内容,我想知道是否有更快的方法来执行此操作?
text = "hey @foo say hi to @bar"
textsplit = text.split()
n = -1
ts2 = textsplit
for x in textsplit:
n += 1
if x[0]== "@":
del ts2[n]
text = ' '.join(ts2)
提前致谢。 (这有点像Removing elements from a list containing specific characters,但这个有点不同。)
答案 0 :(得分:3)
这与您的代码相同:
' '.join(x for x in text.split() if not x.startswith('@'))
答案 1 :(得分:1)
使用re模块和正则表达式,这个怎么样:
print(" ".join(re.sub('^@\w+', '', w) for w in text.split()))
答案 2 :(得分:1)
这更简单,更快捷:
text = "hey @foo say hi to @bar"
newtext = ' '.join([i for i in text.split() if not i.startswith('@')])
答案 3 :(得分:1)
text = "hey @foo say hi to @bar"
newtext = re.sub(' @[!\w]+', '', text)
无需使用任何循环,只需使用正则表达式。
答案 4 :(得分:0)
我按照@elyase和@ chris-johnson的答案来解答你应该使用的实际简单漂亮的代码。
join
的工作原因而略微提高效率。 @ elyase的代码创建了一个生成器对象,然后join
会在运行之前将其转换为列表,我认为这比仅仅创建一个列表要花费更多。但这是一个次要的优化点。
我刚刚在示例代码中发现了一些代码气味,所以想要指出它们。
text = "hey @foo say hi to @bar"
textsplit = text.split()
n = -1
ts2 = textsplit # code smell 1
for x in textsplit:
n += 1 # code smell 2
if x[0]== "@":
del ts2[n] # code smell 3
text = ' '.join(ts2)
代码气味1 :我想你想用ts2 = textsplit
创建一个列表的副本,但这并没有发生。您只需为textsplit
引用的列表创建另一个名称,因此更改ts2
将更改textsplit
,反之亦然。您可以ts2 = textsplit[:]
制作非嵌套列表的副本。
代码气味2 :您正在创建变量n
并通过在每次迭代时手动递增将其用作索引。如果您正在做的事情,请改用for n, x in enumerate(textsplit)
。
代码气味3 :这里有两件事:
ts2[n]
将抛出一个IndexError。如果您要参与索引操作,则每次删除项目时都需要递减n
。但一般来说,索引twiddling是许多错误的来源。如果你不必这样做,就不要这样做。在Python中,你通常不必这样做。
答案 5 :(得分:0)
在我看来,所有其他答案都在假设您希望删除@...
子字符串并在不同字词(或{以外的字符集)之间保持' '
的分隔的情况下运行{1}}),如您的代码所示。但是,这个问题并没有明确指出这是一个目标。而且,既然有可能出现(不要问我)这种行为不正确的情况,我们就去吧!
编辑:现在可读且灵活(与旧代码 - 高尔夫版本相比)
我原来的帖子有点傻,因为代码真的不适合制作;它有效,但就是这样。现在,这可以毫不费力地完成三种类型的子串减法,尽管使用正则表达式可能会做得更好(在那里不太经验)。
' '
text = "hey @foo say hi to @bar"
的常规版本,用于分隔剩余的单词' '
newText = ''.join(
text[i] if text.rfind('@', 0, i+2) <= text.rfind(' ', 0, i+1) else
'' for i in xrange(len(text)))
>>> 'hey say hi to'
newText = ''.join(
text[i] if text.rfind('@', 0, i+1) <= text.rfind(' ', 0, i+1) else
'' for i in xrange(len(text)))
>>> 'hey say hi to '
希望这有所帮助,不知何故!