根据过滤条件将列表划分为块(子列表)

时间:2016-10-26 19:58:02

标签: python list tuples splice

我有一个像这样的列表

a = ['31', '20', '54', '68', '65', '72', '00', '00', '00', '82', '4d', '61', '72', '67', '69', '6e', '00', '00', '00', '00','00', '84', '92', '4d','91']

我想将它们拆分为元组列表并删除零块。

li_tup = [('31', '20', '54', '68', '65', '72'), ('82', '4d', '61', '72', '67', '69', '6e'), ('84', '92', '4d','91')] 

当我使用splice[index:index]时,原始列表保持不变。所以循环遍历同一个项目。如何从原始列表中删除拼接的项目?所以我不必再次迭代它。

3 个答案:

答案 0 :(得分:6)

使用itertools.groupby()

列表理解表达式为:

>>> from itertools import groupby
>>> a = ['31', '20', '54', '68', '65', '72', '00', '00', '00', '82', '4d', '61', '72', '67', '69', '6e', '00', '00', '00', '00','00', '84', '92', '4d','91']

>>> [tuple(group) for is_valid, group in groupby(a, lambda x: x!='00') if is_valid]
[('31', '20', '54', '68', '65', '72'), ('82', '4d', '61', '72', '67', '69', '6e'), ('84', '92', '4d', '91')]

答案 1 :(得分:6)

这是一个不需要导入itertools的列表理解答案:

>>> a = ['31', '20', '54', '68', '65', '72', '00', '00', '00', '82', '4d', '61', '72', '67', '69', '6e', '00', '00', '00', '00','00', '84', '92', '4d','91']
>>> [ tuple(b.strip().split()) for b in ' '.join(a).split('00 ') if b ]
[('31', '20', '54', '68', '65', '72'), ('82', '4d', '61', '72', '67', '69', '6e'), ('84', '92', '4d', '91')]

与其他方法(10,000次迭代)的比较:

  • 使用加入和拆分的方法需要 - 0.214s
  • MosesKoledoye's answer使用 itertools.groupby() for for for循环需要 - 0.372s,
  • anonymous's answer使用带有列表理解的 itertools.groupby() 需要 - 0.321s

(不包括他们的代码导入itertools所需的时间)

答案 2 :(得分:3)

您可以使用itertools.groupby,因为我们事先没有'00'项目的索引:

from itertools import groupby

a = ['31', '20', '54', '68', '65', '72', '00', '00', '00', '82', '4d', '61', '72', '67', '69', '6e', '00', '00', '00', '00','00', '84', '92', '4d','91']

result = []
for i, g in groupby(a, lambda x: x!='00'):
    if i:
        result.append(tuple(g))
print(result)
# [('31', '20', '54', '68', '65', '72'), ('82', '4d', '61', '72', '67', '69', '6e'), ('84', '92', '4d', '91')]