【问题标题】:Python filtering out a list using elements from another listPython使用另一个列表中的元素过滤掉一个列表
【发布时间】:2020-05-19 16:03:24
【问题描述】:

我正在尝试使用另一个列表过滤掉一个列表。但是,我用来过滤另一个列表的列表元素不是相同的字符串。请看我的例子,因为它会更有意义:

mylist = ['14001IB_L1P0', '14001OB_L1P1', '14002IB_L3P0', '14003OB_L1P1', '14001OB_L2P0']
remove_list = ['14001', '14002']

我想从 mylist 中删除以 remove_list 中的值开头的值。 我试过这样做:

filtered_mylist = mylist[:]

for x in remove_list:
    for i in filtered_mylist:
        if x in i:
            print('remove ' +i)
            filtered_mylist.remove(i)
        else:
            print('keep '+i)

但是,结果是这样的:

remove 14001IB_L1P0
keep 14002IB_L3P0
keep 14003OB_L1P1
remove 14001OB_L2P0
keep 14001OB_L1P1
remove 14002IB_L3P0

这就是 filters_mylist 的组成部分:

['14001OB_L1P1', '14003OB_L1P1']

但是,它应该只包含 1 个元素: ['14003OB_L1P1']

在我看来,由于某种原因,循环跳过了第一个循环中的第二个元素“14001OB_L1P1”。为什么会这样?

【问题讨论】:

  • 不要从您当前正在迭代的列表中删除项目,这会导致某些项目被跳过。

标签: python list filter


【解决方案1】:

这里是一个班轮

mylist = list(filter(lambda x: all([x.find(y) != 0 for y in remove_list]), mylist))

#Output
['14003OB_L1P1']

all([x.find(y) != 0 for y in remove_list]) 将返回 True 当且仅当 x 不以来自 remove_list 的单个值开头。

all() 表示都必须是Truex.find(y) != 0 表示x 不以y 开头。

剩下的只是执行过滤器。

【讨论】:

  • 谢谢!这看起来奏效了。我喜欢它包含在 1 行中。不过这对我来说太复杂了,无法理解。您介意解释一下这是如何工作的吗?
【解决方案2】:

这会有帮助吗?

remove_final = []
keep_final = []
for element in mylist:
    if any([element.startswith(x) for x in remove_list]):
        print(f'remove {element}')
        remove_final.append(element)
    else:
        print(f'keep {element}')
        keep_final.append(element)

输出:

remove 14001IB_L1P0
remove 14001OB_L1P1
remove 14002IB_L3P0
keep 14003OB_L1P1
remove 14001OB_L2P0

最终名单:

keep_final
['14003OB_L1P1']

remove_final
['14001IB_L1P0', '14001OB_L1P1', '14002IB_L3P0', '14001OB_L2P0']

【讨论】:

    【解决方案3】:

    希望这段代码对你有所帮助。

    mylist = ['14001IB_L1P0', '14001OB_L1P1', '14002IB_L3P0', '14003OB_L1P1', '14001OB_L2P0']
    remove_list = ['14001', '14002']
    
    filtered_mylist = mylist[:]
    
    for x in remove_list:
    
        i = 0
        while i < len(filtered_mylist):
            if x in filtered_mylist[i]:
                print('remove ' + filtered_mylist[i])
                filtered_mylist.remove(filtered_mylist[i])
            else:
                print('keep '+ filtered_mylist[i])
                i+=1
    

    【讨论】:

      【解决方案4】:

      这是另一种方法 - append 方法。

      尝试使用“过滤功能+追加”来代替删除。这样更安全。

      mylist = ['14001IB_L1P0', '14001OB_L1P1', '14002IB_L3P0', '14003OB_L1P1', '14001OB_L2P0']
      remove_list = ['14001', '14002']
      
      
      def is_valid(item):
          for pattern in remove_list:
              if item.startswith(pattern):
                  return False
          return True
      
      
      res = []
      for item in mylist:
          if is_valid(item):
              res.append(item)
      print(res)
      

      【讨论】:

        猜你喜欢
        • 2018-07-14
        • 2021-04-04
        • 2019-08-03
        • 1970-01-01
        • 2015-10-26
        • 2013-10-29
        • 2022-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多