【问题标题】:Substring filter list elements by another list in PythonPython中另一个列表的子字符串过滤列表元素
【发布时间】:2019-08-03 18:00:59
【问题描述】:

我有两个类似的列表:

list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
list2 = [100, 200]

我想通过list2 的元素对list1 进行子串过滤,并获得如下预期输出:

outcome = ['bj-100-cy', 'sh-200-pd']

做的时候:

list1 = str(list1)
list2 = str(list2)
outcome = [x for x in list2 if [y for y in list1 if x in y]]

我得到这样的结果:['[', '1', '0', '0', ',', ' ', '2', '0', '0', ']']。 我怎样才能正确过滤它?谢谢。

参考相关:

Is it possible to filter list of substrings by another list of strings in Python?

【问题讨论】:

    标签: python string list filter list-comprehension


    【解决方案1】:

    你可以使用正则表达式:

    import re
    
    list1 = ['bj-100-cy', 'bj-101-hd', 'sh-200-pd', 'sh-201-hp']
    list2 = [100, 200]
    
    pattern = re.compile('|'.join(map(str, list2)))
    list(filter(pattern.search, list1))
    # ['bj-100-cy', 'sh-200-pd']
    

    【讨论】:

      【解决方案2】:

      您可以使用内置的filter 方法根据您的条件过滤列表。您的情况需要 python in 运算符在 haystack ([['bj-100-cy','bj-101-hd',...]]) 中搜索 needle([100, 200])。 我们可以使用contains 方法来简化搜索语法。

      代码

      from operator import contains
      filter(lambda x: any(contains(x,str(y)) for y in list2), list1)
      

      示例

      >>> list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
      >>> list2 = [100, 200]
      >>> for item in filter(lambda x: any(contains(x,str(y)) for y in list2), list1):
      ...     print(item)
      ...
      bj-100-cy
      sh-200-pd
      

      【讨论】:

        【解决方案3】:

        另一种列表理解:

        >>> list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
        >>> list2 = [100, 200]
        >>> occur = [i for i in list1  for j in list2 if str(j) in i]
        >>> occur
        ['bj-100-cy', 'sh-200-pd']
        

        【讨论】:

          【解决方案4】:

          你可以试试这个:

          list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
          list2 = [100, 200]
          
          outcome = []
          for item in list1:
              if any(str(i) in item for i in list2):
                  outcome.append(item)
          

          输出:

          ['bj-100-cy', 'sh-200-pd']
          

          【讨论】:

            【解决方案5】:
            list1 = str(list1)
            list2 = str(list2)
            

            您正在使用上述语句将列表转换为字符串。因此,当您在 for 循环中进行迭代时,您是在迭代每个字符,而不是每个单词。

            因此,您应该删除字符串转换,而是按如下方式执行列表推导。 此外,在您的结果文件中,不是检查 list2 中的单词是否在 list1 中,而是检查相反的情况。所以你得到了列表 2 中的 100 和 200 个字符。

            list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
            list2 = [100, 200]
            outcome = [x for x in list1 for y in list2 if str(y) in x]
            

            【讨论】:

              【解决方案6】:

              你可以使用any:

              list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
              list2 = [100, 200]
              list2 = [str(x) for x in list2]
              
              outcome = [s for s in list1 if any(x in s for x in list2)]
              

              any 返回True,如果你给它的任何条件是True

              【讨论】:

                【解决方案7】:

                列表理解和any:

                [i for i in list1 if any(i for j in list2 if str(j) in i)]
                

                any 检查list2 的任何元素是否是被迭代的list1 项(__contains__)的子字符串。

                示例:

                In [92]: list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
                    ...: list2 = [100, 200]
                    ...: 
                
                In [93]: [i for i in list1 if any(i for j in list2 if str(j) in i)]
                Out[93]: ['bj-100-cy', 'sh-200-pd']
                

                【讨论】:

                • 谢谢,我尝试使用您的脚本获取我的真实数据(与此处的示例数据类似),我需要添加list2 = [str(x) for x in list2] 否则我得到TypeError: 'in <string>' requires string as left operand, not int
                • @ahbon 这很奇怪,因为我在str(j):any(i for j in list2 if str(j) in i)中进行了类型转换
                • 是的,我重新读取数据并再次尝试,现在可以了,感谢您对这张海报的所有帮助。
                猜你喜欢
                • 2018-02-12
                • 1970-01-01
                • 1970-01-01
                • 2018-07-14
                • 2021-06-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-08-28
                相关资源
                最近更新 更多