按连续的公共元素拆分列表
Split the list by consecutive common element
我有以下列表,其中仅包含两个字符 'N' 和 'C'
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
我想做的是提取列表中连续的"C"和return索引。
产生类似
的东西
chunk1 = [('C', 'C', 'C', 'C'), [3,4,5,6]]
chunk2 = [('C', 'C'), [8,9]]
# and when there's no C it returns empty list.
如何在 Python 中实现?
我试过了,但没有如我所愿:
from itertools import groupby
from operator import itemgetter
tmp = (list(g) for k, g in groupby(enumerate(ls), itemgetter(1)) if k == 'C')
zip(*tmp)
移动zip(*...)
里面的列表推导:
import itertools as IT
import operator
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
[list(zip(*g))[::-1]
for k, g in IT.groupby(enumerate(ls), operator.itemgetter(1))
if k == 'C']
产量
[[('C', 'C', 'C', 'C'), (3, 4, 5, 6)], [('C', 'C'), (8, 9)]]
在Python2中,list(zip(...))
可以用zip(...)
代替,但是由于在Python3zip
returns中有一个迭代器,所以我们需要 list(zip(...))
。要使解决方案与 Python2 和 Python3 兼容,请在此处使用 list(zip(...))
。
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
def whereMyCharsAt(haystack, needle):
start = None
for ii, char in enumerate(haystack):
if char == needle:
if start is None:
start = ii
else:
if start is not None:
yield [needle] * (ii - start), range(start, ii)
start = None
if start is not None:
yield [needle] * (len(haystack) - start), range(start, len(haystack))
for indexes in whereMyCharsAt(ls, 'C'):
print indexes
这会打印:
(['C', 'C', 'C', 'C'], [3, 4, 5, 6])
(['C', 'C'], [8, 9])
使用生成器函数。您需要做的就是在解压缩组时反转group
。
所以使用 yield zip(*group)[::-1]
from itertools import groupby
from operator import itemgetter
def solve(ls):
for key, group in groupby(enumerate(ls), itemgetter(1)):
if key =='C':
yield zip(*group)[::-1]
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
print list(solve(ls))
[[('C', 'C', 'C', 'C'), (3, 4, 5, 6)], [('C', 'C'), (8, 9)]]
我有以下列表,其中仅包含两个字符 'N' 和 'C'
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
我想做的是提取列表中连续的"C"和return索引。
产生类似
的东西 chunk1 = [('C', 'C', 'C', 'C'), [3,4,5,6]]
chunk2 = [('C', 'C'), [8,9]]
# and when there's no C it returns empty list.
如何在 Python 中实现?
我试过了,但没有如我所愿:
from itertools import groupby
from operator import itemgetter
tmp = (list(g) for k, g in groupby(enumerate(ls), itemgetter(1)) if k == 'C')
zip(*tmp)
移动zip(*...)
里面的列表推导:
import itertools as IT
import operator
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
[list(zip(*g))[::-1]
for k, g in IT.groupby(enumerate(ls), operator.itemgetter(1))
if k == 'C']
产量
[[('C', 'C', 'C', 'C'), (3, 4, 5, 6)], [('C', 'C'), (8, 9)]]
在Python2中,list(zip(...))
可以用zip(...)
代替,但是由于在Python3zip
returns中有一个迭代器,所以我们需要 list(zip(...))
。要使解决方案与 Python2 和 Python3 兼容,请在此处使用 list(zip(...))
。
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
def whereMyCharsAt(haystack, needle):
start = None
for ii, char in enumerate(haystack):
if char == needle:
if start is None:
start = ii
else:
if start is not None:
yield [needle] * (ii - start), range(start, ii)
start = None
if start is not None:
yield [needle] * (len(haystack) - start), range(start, len(haystack))
for indexes in whereMyCharsAt(ls, 'C'):
print indexes
这会打印:
(['C', 'C', 'C', 'C'], [3, 4, 5, 6])
(['C', 'C'], [8, 9])
使用生成器函数。您需要做的就是在解压缩组时反转group
。
所以使用 yield zip(*group)[::-1]
from itertools import groupby
from operator import itemgetter
def solve(ls):
for key, group in groupby(enumerate(ls), itemgetter(1)):
if key =='C':
yield zip(*group)[::-1]
ls = ['N', 'N', 'N', 'C', 'C', 'C', 'C', 'N', 'C', 'C']
print list(solve(ls))
[[('C', 'C', 'C', 'C'), (3, 4, 5, 6)], [('C', 'C'), (8, 9)]]