【问题标题】:List Comprehension for Strings字符串的列表理解
【发布时间】:2018-09-17 02:05:37
【问题描述】:

我有两个列表,如下所示。我想查找第一个列表中的字符串是否在第二个列表中的任何字符串中。出于某种原因,当我尝试运行它时,我得到了一个空列表。

例如:在list5中,字符串'apple'list6'I ate an apple'中。

list5 = ['apple', 'mango', 'sherbet']
list6 = ['I ate an apple', 'I ate two apples', 'I love mango']
print ([x for i,x in enumerate(list5) if x in list6])

对于整数列表,完全相同的事情运行顺利。是否有不同的方式来处理字符串?

list7 = [1, 2, 3, 4, 5]
list8 = [1, 2]
print ([x for i,x in enumerate(list7) if x in list8])  

【问题讨论】:

  • 你正在检查'apple'本身是否是list6的成员,你想检查'apple'是否是list6中任何字符串的子字符串
  • 你会一直处理第一个字符串列表中的单个单词吗?例如,您能否在第一个列表中包含 ['an apple', 'mango', 'sherbert'] 并期望在第二个列表中的任何字符串中匹配 'an apple'

标签: python string python-3.x list list-comprehension


【解决方案1】:

您正在检查apple 是否在列表中,但您想检查列表中是否有任何字符串包含苹果

list5 = ['apple', 'mango', 'sherbet']
list6 = ['I ate an apple', 'I ate two apples', 'I love mango']
[x for x in list5 if any(x in item for item in list6)]
#['apple', 'mango']

编辑

这将创建一个列表列表,其中包含第二个列表中句子的索引,其中包含第一个列表中的单词

list5 = ['apple', 'mango', 'sherbet']
list6 = ['I ate an apple', 'I ate two apples', 'I love mango', '2 apple', 'big apple', 'big mango']
[[i for i, sentence in enumerate(list6) if x in sentence] for x in list5]
#[[0, 1, 3, 4], [2, 5], []]

正如我在评论中所说,在这种情况下字典会更好

{x:[i for i,sen in enumerate(list6) if x in sen] for x in list5}
#{'apple': [0, 1, 3, 4], 'mango': [2, 5], 'sherbet': []}

如果只存储完全匹配项,您可以使用它,但如果第一个列表不只包含单词,这将不起作用,例如,如果 list5 包含“an apple”,这不起作用

{x:[i for i,sen in enumerate(list6) if any(x==item for item in sen.split())] for x in list5}
#{'apple': [0, 3, 4], 'mango': [2, 5], 'sherbet': []}

【讨论】:

  • 我想知道苹果在 list6 中出现的索引是什么,而“任何”方法也没有给我所有的实例。有没有办法获取所有实例及其索引?
  • 所有实例是什么意思?苹果应该是输出的两倍吗?请向我们展示您想要的输出应该是什么样子
  • 如果a字符串包含两个单词,例如'我吃了一个苹果和一个芒果'怎么办?
  • 给出的示例没有多个实例,但如果是这样的话。 list6 = ['我吃了一个苹果','我吃了两个苹果','我爱芒果','2个苹果','大苹果','大芒果']。我想得到 [0,3,4] 的苹果和 [2, 5] 的芒果。基本上它们在该特定列表中的各自索引。只是为了澄清当我说索引时,我的意思是整个字符串。希望我说得通
  • 好吧明白你的意思是输出必须是一个列表吗?因为字典更适合{"apple":[3,4,5]}
【解决方案2】:

您的代码正在检查x 是否是list6 的成员,而您似乎想知道x 是否是list6 中任何成员的子字符串。您可以使用 Python 的 reduce 方法(在 functools 中使用 Python 3)来完成此操作。

list5 = ['apple', 'mango', 'sherbet']
list6 = ['I ate an apple', 'I ate two apples', 'I love mango']

from functools import reduce
print([x for x in list5
         if reduce(lambda exist, s: exist or (x in s), list6, False)])
# ['apple', 'mango']

reduce 调用遍历list6 的所有成员并检查x 是否是子字符串,然后将这些结果与exist(默认为False)进行或运算以返回@987654334 @如果至少找到一次。请参阅functools.reduce 的 Python3 文档以更好地了解其工作原理。

【讨论】:

    【解决方案3】:

    听起来您要求设置交集,在这种情况下,我将绕过并使用集合而不是列表,并使用交集运算符而不是循环,例如 a & b 其中 a 和 b 是集合。

    但是您的示例使您看起来像是在 list6 中的每个字符串中查找 list5 中的子字符串,这可能是完全不同的,我们需要有关您的预期输出的更多信息来帮助您更多。

    另外顺便说一句,你不需要使用 enumerate 因为你没有使用它的值。

    【讨论】:

      【解决方案4】:
      #!python3
      
      import re
      
      list5 = ['apple', 'mango', 'sherbet']
      list6 = ['I ate an apple', 'I ate two apples', 'I love mango']
      
      for item in list6:
          for substr in list5:
              if re.search(r"\b" + re.escape(substr) + r"\b", item):
                  print('"' + substr + '"' + ' is in ' + '"' + item + '"')
      
      '''
      # output
      "apple" is in "I ate an apple"
      "mango" is in "I love mango"
      '''
      
      list7 = [1, 2, 3, 4,5]
      list8 = [1,2]
      
      for substr in list8:
          if substr in list7:
              print(substr, 'is in', list7)
      
      '''
      # output
      1 is in [1, 2, 3, 4, 5]
      2 is in [1, 2, 3, 4, 5]
      '''
      

      【讨论】:

      • 投票给我的人应该自己解释。此代码有效。它可能不是最好的代码,但它仍然有效。
      【解决方案5】:

      一种方法是在列表理解中调用函数。

      不是单行,但逻辑清晰,一找到匹配就短路。

      list5 = ['apple', 'mango', 'sherbet']
      list6 = ['I ate an apple', 'I ate two apples', 'I love mango']
      
      def find_word(x, sentences):
          for item in sentences:
              if x in item:
                  return x
      
      res = [x for x in list5 if find_word(x, list6)]
      
      # ['apple', 'mango']
      

      【讨论】:

        猜你喜欢
        • 2021-04-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-13
        • 1970-01-01
        • 2021-01-02
        • 1970-01-01
        • 2023-02-26
        • 1970-01-01
        相关资源
        最近更新 更多