编辑:
对,有了 OP 中的新信息,这变得简单多了。使用配方将itertools
grouper()
每个人的数据分组为元组:
import itertools
def grouper(iterable, n, fillvalue=None):
"""Collect data into fixed-length chunks or blocks"""
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.zip_longest(*args, fillvalue=fillvalue)
data = ['John', 'Sally', '5', '10', '11', '4', 'John', 'Sally', '3', '7', '7', '10', 'Bill', 'Hallie', '4', '6', '2', '1']
grouper(data, 6)
现在您的数据如下所示:
[
('John', 'Sally', '5', '10', '11', '4'),
('John', 'Sally', '3', '7', '7', '10'),
('Bill', 'Hallie', '4', '6', '2', '1')
]
相比之下,这应该很容易使用。
老答案:
如果您需要创建更多任意链接,而不仅仅是检查连续值:
def offset_iter(iterable, n):
offset = iter(iterable)
consume(offset, n)
return offset
data = ['a', 'a', 'x', 'c', 'e', 'e', 'f', 'f', 'f']
offset_3 = offset_iter(data, 3)
for item, plus_3 in zip(data, offset_3): #Naturally, itertools.izip() in 2.x
print(item, plus_3) #if memory usage is important.
自然,您会希望使用语义上有效的名称。这种方法的优点是它适用于任意迭代,而不仅仅是列表,并且高效且可读,没有任何丑陋、低效的索引迭代。如果您需要在偏移值用完后继续检查(例如,对于其他条件),请使用itertools.zip_longest()
(itertools.izip_longest()
在 2.x 中)。
使用来自的consume()
食谱itertools
。
import itertools
import collections
def consume(iterator, n):
"""Advance the iterator n-steps ahead. If n is none, consume entirely."""
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(itertools.islice(iterator, n, n), None)
但是,我会非常怀疑在这种情况下您是否需要重新检查您的数据结构。
原答案:
我不确定你的目标是什么,但从我收集到的你可能想要itertools.groupby()
:
>>> import itertools
>>> data = ['a', 'a', 'x', 'c', 'e', 'e', 'f', 'f', 'f']
>>> grouped = itertools.groupby(data)
>>> [(key, len(list(items))) for key, items in grouped]
[('a', 2), ('x', 1), ('c', 1), ('e', 2), ('f', 3)]
当有(任意大)重复项目运行时,您可以使用它来解决问题。值得注意的是,您可以提供itertools.groupby()
一个key
参数,该参数将根据您想要的任何因素对它们进行分组,而不仅仅是平等。