Python 通过将正则表达式与元素匹配来拆分列表

Python 通过将正则表达式与元素匹配来拆分列表,python,regex,list,Python,Regex,List,我有一个列表,其中有一些特定的元素。我想根据这些元素将该列表分为“子列表”或不同的列表。例如: test_list = ['a and b, 123','1','2','x','y','Foo and Bar, gibberish','123','321','June','July','August','Bonnie and Clyde, foobar','today','tomorrow','yesterday'] import re element_regex = re.compile(r

我有一个列表,其中有一些特定的元素。我想根据这些元素将该列表分为“子列表”或不同的列表。例如:

test_list = ['a and b, 123','1','2','x','y','Foo and Bar, gibberish','123','321','June','July','August','Bonnie and Clyde, foobar','today','tomorrow','yesterday']
import re
element_regex = re.compile(r'[A-Z a-z]+ and [A-Z a-z]+')
new_list = [test_list[i:(i+4)] for i, x in enumerate(test_list) if element_regex.match(x)]
如果某个元素与“某物和某物”匹配,我想将其拆分为子列表:

new_list = [['a and b, 123', '1', '2', 'x', 'y'], ['Foo and Bar, gibberish', '123', '321', 'June', 'July', 'August'], ['Bonnie and Clyde, foobar', 'today', 'tomorrow', 'yesterday']]
到目前为止,如果在特定元素之后有固定数量的项目,我可以完成这项工作。例如:

test_list = ['a and b, 123','1','2','x','y','Foo and Bar, gibberish','123','321','June','July','August','Bonnie and Clyde, foobar','today','tomorrow','yesterday']
import re
element_regex = re.compile(r'[A-Z a-z]+ and [A-Z a-z]+')
new_list = [test_list[i:(i+4)] for i, x in enumerate(test_list) if element_regex.match(x)]

这几乎是存在的,但在特定的兴趣元素之后并不总是有三个元素。有没有比在每一个项目上循环更好的方法?

如果你想要一行

new_list = reduce(lambda a, b: a[:-1] + [ a[-1] + [ b ] ] if not element_regex.match(b) or not a[0] else a + [ [ b ] ], test_list, [ [] ])
行。不过,最好使用更详细的变体

我在4核i7@2.1 GHz上做了一些速度测量。timeit模块将此代码运行了1.000.000次,需要11.38秒。使用itertools模块中的
groupby
(另一个答案中的Kasras变体)需要9.92秒。最快的版本是我建议的详细版本,只需5.66秒:

new_list = [[]]
for i in test_list:
    if element_regex.match(i):
        new_list.append([])
    new_list[-1].append(i)

如果你想要一艘班轮

new_list = reduce(lambda a, b: a[:-1] + [ a[-1] + [ b ] ] if not element_regex.match(b) or not a[0] else a + [ [ b ] ], test_list, [ [] ])
行。不过,最好使用更详细的变体

我在4核i7@2.1 GHz上做了一些速度测量。timeit模块将此代码运行了1.000.000次,需要11.38秒。使用itertools模块中的
groupby
(另一个答案中的Kasras变体)需要9.92秒。最快的版本是我建议的详细版本,只需5.66秒:

new_list = [[]]
for i in test_list:
    if element_regex.match(i):
        new_list.append([])
    new_list[-1].append(i)

您不需要
regex
,只需使用:

首先,我们通过lambda函数
lambda i:'和'in i
对列表进行分组,该函数在i中查找包含
和“
的元素!然后我们有这个:

>>> g_list
[['a and b, 123'], ['1', '2', 'x', 'y'], ['Foo and Bar, gibberish'], ['123', '321', 'June', 'July', 'August'], ['Bonnie and Clyde, foobar'], ['today', 'tomorrow', 'yesterday']]

因此,我们必须在这里连接使用
add
运算符和列表理解的两对列表

您不需要
regex
为此,只需使用:

首先,我们通过lambda函数
lambda i:'和'in i
对列表进行分组,该函数在i中查找包含
和“
的元素!然后我们有这个:

>>> g_list
[['a and b, 123'], ['1', '2', 'x', 'y'], ['Foo and Bar, gibberish'], ['123', '321', 'June', 'July', 'August'], ['Bonnie and Clyde, foobar'], ['today', 'tomorrow', 'yesterday']]

因此,我们必须在这里连接使用
add
运算符和列表理解的两对列表

看起来好像您想在
“Foo和Bar,gibberish”
上拆分,但您的正则表达式将与之不匹配(它将在Bar后面的逗号上失败)。您是否缺少单引号<代码>'Bonnie and Clyde,foobar'也有同样的问题。至于更好的方法,除非你不能在一行中有两个匹配项或存在其他限制,否则你真的需要检查每个条目,因为它可能是一个新列表的开始。看起来你想在
“Foo and Bar,gibberish”
上拆分,但你的正则表达式将不匹配它(它将在条后的逗号上失败)。您是否缺少单引号<代码>'Bonnie and Clyde,foobar'也有同样的问题。至于更好的方法,除非你不能在一行中有两个匹配项或存在其他限制,否则你真的需要检查每个条目,因为它可能是一个新列表的开始。虽然不是很pythonic,这就是我要找的。虽然不是很pythonic,这就是我要找的。谢谢!我选择了菲利普斯的答案。但你现在说服我多读一些关于itertools的内容。itertools似乎是我大部分python问题的答案。是的,itertools是python模块中的传奇!但是大约有一艘班轮不能保证它跑得更快这两种变体在速度方面没有太大区别。在我的电脑上,speedit使用reduce()运行1M需要11.38s,使用itertools变体(如果还使用regexp)需要9.92s。我喜欢你的变体的原因是可读性更好。我想我还是更喜欢
for
循环而不是两者。我将在我的答案中添加一些内容。@Phillip当问题是关于处理列表时,我首先想到的是
itertools
!;)谢谢我选择了菲利普斯的答案。但你现在说服我多读一些关于itertools的内容。itertools似乎是我大部分python问题的答案。是的,itertools是python模块中的传奇!但是大约有一艘班轮不能保证它跑得更快这两种变体在速度方面没有太大区别。在我的电脑上,speedit使用reduce()运行1M需要11.38s,使用itertools变体(如果还使用regexp)需要9.92s。我喜欢你的变体的原因是可读性更好。我想我还是更喜欢
for
循环而不是两者。我将在我的答案中添加一些内容。@Phillip当问题是关于处理列表时,我首先想到的是
itertools
!;)