我正在尝试从一个列表创建一个列表列表。如果新的列表列表具有相同数量的元素,则可以执行此操作,但是情况并非总是如此
如前所述,当列表中的元素数相同时,下面的函数可以工作。
我尝试使用正则表达式来确定元素是否与模式匹配
pattern2=re.compile(r'\d\d\d\d\d\d')
,因为我的新列表列表中的第一个值将始终为6位数字,并且它将是唯一遵循该格式的数字。但是,我不确定让它在下一场比赛中停止并创建另一个列表的语法
def chunks(l,n):
for i in range(0,len(l),n):
yield l[i:i+n]
如果列表列表包含相同数量的元素,则上面的代码有效
下面是我的期望。
OldList=[111111,a,b,c,d,222222,a,b,c,333333,a,d,e,f]
DesiredList=[[111111,a,b,c,d],[222222,a,b,c],[333333,a,d,e,f]]
非常感谢。
欢呼
答案 0 :(得分:1)
这可能是一种效率更高的方法(循环次数更少),但这是一种找到断点索引,然后将列表从索引切成索引的方法,将None
附加到末尾索引列表以捕获其余项目。如果您的6位数字确实是字符串,则可以消除str()
内的re.match()
。
import re
d = [111111,'a','b','c','d',222222,'a','b','c',333333,'a','d','e','f']
indexes = [i for i, x in enumerate(d) if re.match(r'\d{6}', str(x))]
groups = [d[s:e] for s, e in zip(indexes, indexes[1:] + [None])]
print(groups)
# [[111111, 'a', 'b', 'c', 'd'], [222222, 'a', 'b', 'c'], [333333, 'a', 'd', 'e', 'f']]
答案 1 :(得分:0)
您可以使用折叠。
首先,定义一个函数以定位开始标志:
>>> def is_start_flag(v):
... return len(v) == 6 and v.isdigit()
如果这些标志与您期望的标志不完全相同,或者排除一些误报,或者甚至需要使用正则表达式,这将很有用。
然后使用functools.reduce
:
>>> L = d = ['111111', 'a', 'b', 'c', 'd', '222222', 'a', 'b', 'c', '333333', 'a', 'd', 'e', 'f']
>>> import functools
>>> functools.reduce(lambda acc, x: acc+[[x]] if is_start_flag(x) else acc[:-1]+[acc[-1]+[x]], L, [])
[['111111', 'a', 'b', 'c', 'd'], ['222222', 'a', 'b', 'c'], ['333333', 'a', 'd', 'e', 'f']]
如果下一个元素x
是开始标志,则将新列表[x]
附加到累加器。否则,将元素添加到当前列表,即累加器的最后一个列表。