Я хочу использовать метод массива
forEach
как цикл внутри генератора, а не для.Нет, вы этого не делаете.
't, потому что вы не можете . Это буквально невозможно. Не пытайтесь.
То, что вы , вероятно, , хочет сократить цикл
for
, чтобы быть более кратким, особенно если у вас уже есть массив или итератор.Простым решением является использование
yield*
:function* someFunction () { yield* someArray }
yield*
передаст итерацию итератору, с которой вы его используете, и гораздо более кратким, чем пытаясь использовать.forEach
.
Существует много способов сделать кластерный анализ . Один простой подход - посмотреть размер зазора между последовательными элементами данных:
def cluster(data, maxgap):
'''Arrange data into groups where successive elements
differ by no more than *maxgap*
>>> cluster([1, 6, 9, 100, 102, 105, 109, 134, 139], maxgap=10)
[[1, 6, 9], [100, 102, 105, 109], [134, 139]]
>>> cluster([1, 6, 9, 99, 100, 102, 105, 134, 139, 141], maxgap=10)
[[1, 6, 9], [99, 100, 102, 105], [134, 139, 141]]
'''
data.sort()
groups = [[data[0]]]
for x in data[1:]:
if abs(x - groups[-1][-1]) <= maxgap:
groups[-1].append(x)
else:
groups.append([x])
return groups
if __name__ == '__main__':
import doctest
print(doctest.testmod())
Во-первых, вы можете легко преобразовать любую последовательность в последовательность пар смежных элементов. Просто попробуйте, сдвиньте его вперед и застегните несмещенные и несмещенные копии. Единственный трюк в том, что вам нужно начать с (<something>, 1)
или (139, <something>)
, потому что в этом случае мы хотим не каждую пару элементов, а пару для каждого элемента:
def pairify(it):
it0, it1 = itertools.tee(it, 2)
first = next(it0)
return zip(itertools.chain([first, first], it0), it1)
(This это не самый простой способ написать его, но я думаю, что это может быть наиболее читаемым для людей, которые не знакомы с itertools
.)
>>> a = [1, 6, 9, 100, 102, 105, 109, 134, 139]
>>> list(pairify(a))
[(1, 1), (1, 6), (6, 9), (9, 100), (100, 102), (102, 105), (105, 109), (109, 134), (134, 139)]
Затем, с немного более сложную версию ключа Ned Batchelder, вы можете просто использовать groupby
.
Однако, я думаю, в этом случае это будет сложнее, чем явный генератор, который делает то же самое.
def cluster(sequence, maxgap):
batch = []
for prev, val in pairify(sequence):
if val - prev >= maxgap:
yield batch
batch = []
else:
batch.append(val)
if batch:
yield batch
Это найдет группы:
nums = [1, 6, 9, 100, 102, 105, 109, 134, 139]
for k, g in itertools.groupby(nums, key=lambda n: n//10):
print k, list(g)
0 [1, 6, 9]
10 [100, 102, 105, 109]
13 [134, 139]
Обратите внимание, что если nums на самом деле не сортируется по мере того, как показывает ваш образец, вам нужно сначала его отсортировать.
[1, 6, 9, 99, 100, 134, 139]
будет группировать 99 i> и 100 i> в разные группы. Было бы лучше вычислить различия между последовательными точками данных, чтобы определить, где начинается один кластер, а другой заканчивается.
– Raymond Hettinger
9 February 2013 в 03:39
groupby
.)
– abarnert
19 March 2013 в 06:33