如何匹配列表的一部分并返回python

时间:2016-10-29 20:52:53

标签: python

我们存储了行

['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'POST', '2016-10-28T09:29:07.940000'],

在一个名为data的数组中。我们知道它在那里因为:

>>> print data
[['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'POST', '2016-10-28T09:29:07.940000'], ['worker42', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'HANDLE', '2016-10-28T09:29:07.970000'], ['frontend7', '2ef630e2-64fb-4100-8a04-07c4d25887b7', 'GET', '2016-10-28T09:29:07.970000'], ['frontend9', 'a9af2495-f2f0-42e3-81fa-d99d4bac5b9c', 'GET', '2016-10-28T09:29:07.990000'], ['frontend19', '0336af66-edff-48e0-958c-42d09d0efd7a', 'GET', '2016-10-28T09:29:08.010000'], ['frontend14', 'ebc80de2-3708-4aa5-88e4-d3c08a018961', 'GET', '2016-10-28T09:29:08.030000'], ['frontend16', '14fd9242-7a0c-4f42-ab0c-f8e6de21f948', 'GET', '2016-10-28T09:29:08.040000'], ['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'RESPOND', '2016-10-28T09:29:08.050000'], ['frontend5', '8b3e6d9f-abbc-46c0-a458-05e6fd3bbe6c', 'POST', '2016-10-28T09:29:08.060000'], ['frontend3', 'd8389212-c91e-450b-8745-2cb121cb9623', 'POST', '2016-10-28T09:29:08.090000']]

甚至可以拉出整条线:

>>> print data[0]
['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'POST', '2016-10-28T09:29:07.940000']

可以拉出线的任何部分:

>>> print data[0][0]
frontend2

问题:我需要查找以frontend2开头并包含RESPOND的行,并拉出其中的其他部分。

有人可能会认为索引至少会找到它,但不会:

>>> data.index("frontend2")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'frontend2' is not in list
>>>

这样做的pythonic方式是什么?
理想情况下我可以这样 数据[frontend2] [2] 它将扫描列表,找到匹配的第一行,并返回2索引项。 (或者,对于脚本的另一部分,覆盖2项而不触及其余部分。)

过滤器会给我所有行;大概我可以进一步过滤以获得获取线?我没有找到好的文件;任何解释都表示赞赏。在列表推导模式下执行此操作会产生相同的结果。

>>> print filter(lambda x: 'frontend2' in x, data)
[['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'POST', '2016-10-28T09:29:07.940000'], ['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'RESPOND', '2016-10-28T09:29:08.050000']]

一个可能的解决方案可能是使用正则表达式并对其进行过滤,但看起来似乎应该有更好的方法。

2 个答案:

答案 0 :(得分:1)

要使用列表理解,您必须在过滤器中应用所有条件以匹配所需的子列表:

>>> [lst for lst in data if  lst[0]=='frontend2' and 'RESPOND' in lst]
[['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'RESPOND', '2016-10-28T09:29:08.050000']]

答案 1 :(得分:0)

备选方案1:显而易见的

一种非常明显的方法,可以扫描列表中的每个元素并查找所需的两个标记:

for line in data:
   if 'frontend2' in line and 'RESPOND' in line:
       print line

备选方案2:效率更高

更有效的替代方案,如果您知道该行必须frontend2开始

for line in data:
    if line[0] == 'frontend2' and 'RESPOND' in line:
        print line

备选方案3:使用过滤器

使用过滤器和您需要的所有条件的另一种选择:

print filter(lambda x: 'frontend2' in x and 'RESPOND' in x, data)
>>> [['frontend2', 'ac1b360e-daa8-4102-bc7e-aae01ac5f6ab', 'RESPOND', '2016-10-28T09:29:08.050000']]