关于 python 中各种正则表达式和列表长度的条件语句

Conditional statment regarding various regex and length of a list in python

我有以下列表:

  ['E12.2', 'E16.1', 'E15.1']
  ['E10.1', 'I11.2', 'I10.1_27353757']
  ['E16.1', 'E18.1', 'E17.3']
  ['E1.8', 'I12.1_111682336', 'I12.1_111682195']
  ['E55.1', 'E57.1', 'E56.1','E88.1']
  ['U22.3', 'U22.6_13735517', 'U23.1']

我想设置一个条件来过滤掉 a) 长度等于 3 b) 不包含 '_' c) 不包含字母的列表 'U' 我正在尝试在一行中实施,我该怎么做?我有以下条件,我知道你可以使用正则表达式模块来匹配列表中的正则表达式,但我可以在一行中完成所有条件吗?

 if(len(fin_list) == 3) 

这是一种可能的方式:

lists = [['E12.2', 'E16.1', 'E15.1'],
         ['E10.1', 'I11.2', 'I10.1_27353757'],
         ['E16.1', 'E18.1', 'E17.3'],
         ['E1.8', 'I12.1_111682336', 'I12.1_111682195'],
         ['E55.1', 'E57.1', 'E56.1','E88.1'],
         ['U22.3', 'U22.6_13735517', 'U23.1']]

for lst in lists:
    if len(lst) != 3 and not any('_' in item or 'U' in item for item in lst):
        print(lst)

# Output:
# ['E55.1', 'E57.1', 'E56.1', 'E88.1']

这里有趣的一点是在生成器表达式上使用 any。为了分解它,它遍历 lst 中的每个 item 并应用测试以查看 _U 是否在其中。该列表理解导致列表中的每个项目 True/Falseany 然后寻找第一个 True。如果它找到一个,它会立即 returns True。如果找不到,则 returns False.

编辑

好的,我们显然已经进入 "Just because you can doesn't mean you should," 领域,但这里有一个解决方案,其中包含评论中引入的新条件:

from collections import Counter
import re

lists = [['E12.2', 'E16.1', 'E15.1'],
         ['E10.1', 'I11.2', 'I10.1_27353757'],
         ['E16.1', 'E18.1', 'E17.3'],
         ['E1.8', 'I12.1_111682336', 'I12.1_111682195'],
         ['E55.1', 'E57.1', 'E56.1','E88.1'],
         ['U22.3', 'U22.6_13735517', 'U23.1'],
         ['E7.2', 'E9.5', 'E9.3']]

for lst in lists:
    if (len(lst) != 3 and not any('_' in item or 'U' in item for item in lst) and
            (Counter(match.groups(1) for match in [re.match(r'E(\d+)\.', item) for item in lst] if match is not None)
             .most_common(1) or [(None, 1)])[0][1] == 1):
        print(lst)

# Output:
# ['E55.1', 'E57.1', 'E56.1', 'E88.1']

Counter统计东西,re.match试图找到Es之后的数字,而.most_common(1) or [(None, 1)]是为了确保即使没有匹配的元素,我们仍然可以对结果进行索引并查找出现次数最多的结果。

虽然之前的代码没问题,但现在这段代码很糟糕,应该移出到另一个函数中。 :-)

一行:

ls= [['E12.2', 'E16.1', 'E15.1'],
  ['E10.1', 'I11.2', 'I10.1_27353757'],
  ['E16.1', 'E18.1', 'E17.3'],
  ['E1.8', 'I12.1_111682336', 'I12.1_111682195'],
  ['E55.1', 'E57.1', 'E56.1','E88.1'],
  ['U22.3', 'U22.6_13735517', 'U23.1']]

print(list(filter(lambda l : not any(('_' in x or 'U' in x) for x in l),filter(lambda l : len(l)!=3,ls))))

结果:

[['E55.1', 'E57.1', 'E56.1', 'E88.1']]

我承认这很复杂,但符合规格,因为它是单线的:

  • 外部过滤条件是:否定(下划线或 U 不包含在列表的任何元素中)。
  • 内部过滤条件:list len != 3。最好从这里开始,以避免对元素进行不必要的处理。