【问题标题】:Doubts about string对字符串的怀疑
【发布时间】:2019-08-27 16:47:43
【问题描述】:

所以,我正在使用python做一个练习,我尝试使用终端逐步了解发生了什么,但我没有。

我主要想了解为什么条件只返回索引 0。 看'casino' in [Casinoville].lower() 不是一回事吗?

运动:

  • 获取文档列表(每个文档都是一个字符串)和一个关键字。 将索引值列表返回到包含关键字的所有文档的原始列表中。

运动解决方案

def word_search(documents, keyword):
    indices = [] 
    for i, doc in enumerate(documents):

        tokens = doc.split()
        normalized = [token.rstrip('.,').lower() for token in tokens]

        if keyword.lower() in normalized:
            indices.append(i)
    return indices

我的解决方案

def word_search(documents, keyword):
    return [i for i, word in enumerate(doc_list) if keyword.lower() in word.rstrip('.,').lower()]

运行

>>> doc_list = ["The Learn Python Challenge Casino.", "They bought a car", "Casinoville"]

预期输出

>>> word_search(doc_list, 'casino')
>>> [0]

实际输出

>>> word_search(doc_list, 'casino')
>>> [0, 2]

【问题讨论】:

  • 提示:将这两行输入到解释器中:'casino' in 'casinoville''casino' in ['casinoville']。两者有什么区别?
  • @glibdud 是关于我很困惑为什么'casino' in 'casinoville' 返回True'casino' in ['casinoville'] 返回False,为什么会这样?
  • documentation 始终是您尝试了解语言功能如何工作的好起点。请参阅本节的前两段。

标签: python-3.x string


【解决方案1】:

让我们试着理解其中的区别。

“结果”函数可以用list-comprehension来写:

def word_search(documents, keyword):
    return [i for i, word in enumerate(documents) 
                if keyword.lower() in 
                    [token.rstrip('.,').lower() for token in word.split()]]

问题发生在字符串:"Casinoville",索引为2

查看输出:

print([token.rstrip('.,').lower() for token in doc_list[2].split()])
# ['casinoville']

问题是这样的:你尝试检查一个单词是否在列表中。答案是True,仅当所有字符串都匹配时(这是预期的输出)。

但是,在您的解决方案中,您只检查单词是否包含子字符串。在这种情况下,条件instring 本身,而不是list

看到它:

# On the list : 
print('casino' in [token.rstrip('.,').lower() for token in doc_list[2].split()])
# False

# On the string:
print('casino' in [token.rstrip('.,').lower() for token in doc_list[2].split()][0])
# True

因此,在第一种情况下,"Casinoville" 在第二种情况下不包括在内。

希望有帮助!

【讨论】:

  • 很高兴为您提供帮助!快乐编码:-)
【解决方案2】:

问题是“将索引值列表返回到包含关键字的所有文档的原始列表中”。

你只需要考虑单词。

在“Casinoville”案例中,没有“casino”这个词,因为这个案例只有“Casinoville”这个词。

【讨论】:

  • 是的,但我想了解的是,在练习解决方案中,条件if keyword.lower() in normalized: 在最后一个索引中返回False,如何?因为在我的解决方案中返回 True 并让我感到困惑。
【解决方案3】:

当您使用in 运算符时,结果取决于右侧对象的类型。当它是一个列表(或大多数其他类型的容器)时,您会得到一个精确的成员资格测试。所以'casino' in ['casino']True,但'casino' in ['casinoville']False,因为字符串不相等。

is 的右侧是一个字符串时,它会做一些不同的事情。它不是针对单个字符(如果您将它们视为序列,这就是字符串包含的内容)寻找精确匹配,而是进行子字符串匹配。所以'casino' in 'casinoville'Truecasino in 'montecasino''casino' in 'foocasinobar' 也是如此(检查的不仅仅是前缀)。

对于您的问题,您只希望与整个单词完全匹配。参考解决方案使用str.split 来分隔单词(没有参数它会在任何类型的空格上拆分)。然后它会稍微清理一下单词(去掉标点符号),然后对字符串列表进行 in 匹配。

您的代码永远不会拆分您传递的字符串。因此,当您进行in 测试时,您正在对整个文档进行子字符串匹配,当您匹配较大单词的一部分时,您会得到误报。

【讨论】: