я группа список его разница между индексом и значением:
from itertools import groupby
lst = [1,3,4,5]
result = []
for key, group in groupby(enumerate(lst), key = lambda (i, value): value - i):
result.append([value for i, value in group])
print result
[[1], [3, 4, 5]]
Что я сделал?
# at first I enumerate every item of list:
print list(enumerate(lst))
[(0, 1), (1, 3), (2, 4), (3, 5)]
# Then I subtract the index of each item from the item itself:
print [ value - i for i, value in enumerate(lst)]
[1, 2, 2, 2]
# As you see, consecutive numbers turn out to have the same difference between index and value
# We can use this feature and group the list by the difference of value minus index
print list(groupby(enumerate(lst), key = lambda (i, value): value - i))
[(1, <itertools._grouper object at 0x104bff050>), (2, <itertools._grouper object at 0x104bff410>)]
# Now you can see how it works. Now I just want to add how to write this in one logical line:
result = [ [value for i, value in group]
for key, group in groupby(enumerate(lst), key = lambda (i, value): value - i)]
print result
[[1], [3, 4, 5]]
подхода для определения последовательных кратного п
Давайте посмотрим на этот список,
lst = [1,5,10,11,12,13,14,15,17,21,24,26,28,30]
особенно на различиях между соседними элементами и различием разностей три последовательных элементов :
1, 5, 10, 11, 12, 13, 14, 15, 17, 21, 24, 26, 28, 30
4, 5, 1, 1, 1, 1, 1, 2, 4, 3, 2, 2, 2
1, -4, 0, 0, 0, 0, 1, 2, -1, -1, 0, 0
Мы видим, что в третьей строке есть нули, всякий раз, когда в первой строке есть соединительные кратные. Если мы математически мыслим, то 2-я производная от линейных сечений функций также равна нулю. Так что позволяет использовать это свойство ...
«второй производной» списка lst
можно вычислить, как этот
lst[i+2]-2*lst[i+1]+lst[i]
Обратите внимание, что это определение разности второго порядка «выглядит» два индекса вперед. Теперь вот код обнаружения последовательных мультипликатора:
from itertools import groupby
# We have to keep track of the indexes in the list, that have already been used
available_indexes = set(range(len(lst)))
for second_order_diff, grouper in groupby(range(len(lst)-2), key = lambda i: lst[i+2]-2*lst[i+1]+lst[i]):
# store all not-consumed indexes in a list
grp_indexes = [i for i in grouper if i in available_indexes]
if grp_indexes and second_order_diff == 0:
# There are consecutive multiples
min_index, max_index = grp_indexes[0], grp_indexes[-1] + 2
print "Group from ", lst[min_index], "to", lst[max_index], "by", lst[min_index+1]-lst[min_index]
available_indexes -= set(range(min_index, max_index+1))
else:
# The not "consumed" indexes in this group are not consecutive
for i in grp_indexes:
print lst[i]
available_indexes.discard(i)
# The last two elements could be lost without the following two lines
for i in sorted(available_indexes):
print lst[i]
Выход:
1
5
Group from 10 to 15 by 1
17
21
Group from 24 to 30 by 2
В '[1,3,4,5] -> [[1], [3,4 , 5]] 'почему это вывод' [[1], [3,4,5]] ', а не' [[1,3], [4,5]] '? Должны ли мы выбрать разделение, чтобы максимизировать длины суб-срезов? – Bakuriu
Почему вы хотите: '[1,3,5,6,7] -> [[1], [3], [5,6,7]]' вместо '[[1,3], [ 5,6,7]] 'в результате? Можете ли вы объяснить логику после ожидаемых результатов? Я не вижу ни одного * множественного *, кроме того, что любое натуральное число кратно 1, поэтому не имеет никакого смысла ваш комментарий о «кратных 1 и 2». Похоже, вы смотрите на * разницу * между последовательными номерами, но потом я не могу понять некоторые ваши результаты. – Bakuriu
Или даже: '[[1, 3, 5], [6, 7]]' – hughdbrown