检查字符串中是否包含空格

54
' ' in word == True

我正在编写一个程序,用于检查字符串是否为单词。为什么这样不起作用,有没有更好的方法来检查一个字符串没有空格/是单个单词。


你说它不工作是什么意思?你是否遇到了语法错误?还是根本没有出现任何错误? - SilentGhost
另外,在您的评论中粘贴代码也是可以的,只要确保格式正确即可。 - Rob Lourens
6
不要使用 expression == True 来测试真值。直接使用 expression 就可以了! - Andrew Jaffe
12个回答

101

== 的优先级高于 in,所以你实际上在测试 word == True

>>> w = 'ab c'
>>> ' ' in w == True
1: False
>>> (' ' in w) == True
2: True

但你根本不需要== Trueif需要一个[可以评估为True或False的东西],而' ' in word将被评估为true或false。 因此,if ' ' in word: ...就可以了:

>>> ' ' in w
3: True

4
它无法匹配所有种类的空格:\n、\r、' '等。如果需要匹配它们,最好使用re模块,使用\s上的match方法。这会产生更好的分词器。 - Guillaume Lebourgeois
3
编程中让人讨厌的问题:... == True... != False,以及任何类似的变体。 - Stephen
2
顺便说一下,Jukka Suomela的解释比我的更正确。按照我的解释,你将测试word==True然后是' ' in True,这没有意义。 - Rob Lourens

24

使用if " " in word:代替 if " " in word == True:

解释:

  • 在Python中,例如a < b < c等同于(a < b) and (b < c)
  • 对于任何比较运算符的连锁,包括in,都是一样的!
  • 因此,' ' in w == True相当于(' ' in w) and (w == True),这不是你想要的。

1
哇,我知道 <== 的工作方式就像你描述的那样,但我没有意识到 in 也是这样。我一直以为将它们组合起来会被视为 a in (b == c)(a in b) == c。要想看到它真正被解释为 Jukka 所说的那样,您可以尝试 'a' in 'abc' == 'abc'。它是 True,但如果按照我提出的其他两种方式进行解释,则会变成 False - ArtOfWarfare

15
有很多方法可以做到这一点:
t = s.split(" ")
if len(t) > 1:
  print "several tokens"

为确保它适用于各种空间,您可以使用re模块:
import re
if re.search(r"\s", your_string):
  print "several words"

2
你不需要使用正则表达式来检查每种空格,只需省略传递给s.split()" ",因为默认情况下包括所有空格:https://docs.python.org/3/library/stdtypes.html#str.split - roganartu

4
你可以尝试这样做,如果发现有空格,它将返回第一个空格的位置。
if mystring.find(' ') != -1:
    print True
else:
    print False

mystring.find(' ') != -1 布尔值。 - SilentGhost
这可以简写为 print mystring.find(' ') != -1 - Tim Pietzcker

3
你可以在Python 3中使用're'模块。
如果你确实需要使用,可以这样做:
re.search('\s', word)

这应该返回“true”(如果有匹配项)或“false”(如果没有匹配项)。

1
这不等同于(也匹配\t\n\r\f\v与普通空格相邻),并引入了大量的开销。快速检查显示" " in word48.5ns,而re.search("\s", word)873ns,慢了一个数量级以上。正则表达式应仅用于真正更复杂的任务。 - Alex Povel
更重要的是实际执行 OP 想要的操作。在这种情况下,除非他们逐字逐句地解析整本书,否则 900ns 或 50ns 很可能不相关,与未检测字符串是否包含空格相比。 - Regretful

1

你提到了一般的空格,而不仅仅是空格。我发现使用 isidentifier 可以解决问题。根据 W3 学校的说法:

如果一个字符串只包含字母数字(a-z)和(0-9)或下划线(_),则该字符串被认为是有效的标识符。有效的标识符不能以数字开头,也不能包含任何空格。

因此,如果这符合您的要求,isidentifier 是快速且易于使用的。

有人提到正则表达式的效率,我很好奇:

import timeit

setup='import re; rs="\s"; rc=re.compile(rs); s="applebananacanteloupe"'
stm1='re.search(rs,s)'
stm2='re.search(rc,s)'
stm3='" " in s'
stm4='s.isidentifier()'

timeit.repeat(stm1,setup)
# result: [0.9235025509842671, 0.8889087940042373, 0.8771460619755089, 0.8753634429886006, 1.173506731982343]

timeit.repeat(stm2,setup)
# results: [1.160843407997163, 1.1500899779784959, 1.1857644470001105, 1.1485740720236208, 1.2856045850203373]
# compiled slower than uncompiled? Hmm, I don't get regex...

timeit.repeat(stm3,setup)
# [0.039073383988579735, 0.03403249100665562, 0.03481135700712912, 0.034628107998287305, 0.03392893000273034]

timeit.repeat(stm4,setup)
# [0.08866660299827345, 0.09206177099258639, 0.08418851799797267, 0.08478381999884732, 0.09471498697530478]

所以,isidentifier 几乎和 in 一样快,比正则表达式快10倍。需要注意的是,从技术上讲,Python 对标识符的定义可能会发生变化 - 但如果确实发生了变化,您的代码也很可能需要进行一些改动。


1
如果你将stm2改为stm2='rc.search(s)',你会注意到编译后的查询比未编译的查询更快,对于我的机器来说,编译后的版本比未编译的版本快2倍到4倍。 - undefined

1
你可以使用word.strip(" ")来从字符串中删除任何前导/尾随空格 - 在if语句之前应该这样做。这样,如果有人输入像" test "这样的输入,您的程序仍将正常工作。
话虽如此,if " " in word:将确定字符串是否包含任何空格。如果它不起作用,请提供更多信息。

0
word = ' '
while True:
    if ' ' in word:
        word = raw_input("Please enter a single word: ")
    else:
        print "Thanks"
        break

这是更符合惯用法的 Python 写法 - 不需要与 True 或 False 进行比较,只需使用表达式 ' ' in word 返回的值即可。

此外,对于如此小的代码片段,您不需要使用 pastebin - 只需将代码复制到您的帖子中,并使用小的 1 和 0 按钮使您的代码看起来像代码即可。


0
使用这个:
word = raw_input("Please enter a single word : ")
while True:
    if " " in word:
        word = raw_input("Please enter a single word : ")
    else:
        print "Thanks"
        break

0
def word_in(s):
   return " " not in s 

4
也许考虑向问题的作者解释为什么他的解决方案不起作用,以及为什么您认为自己的更好。 - Ente

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接