У меня есть список индексов как таковых:
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
и мне дается:
pattern_width = 4
n = pattern_width
final_list = []
Как мне пройти через список, анализируя n элементов за раз, в котором, если есть случай, когда все элементы имеют равные значения, они добавляются в пустой список?
Итак, здесь, поскольку первые 4 элемента равны [5, 5, 5, 5], значение 5 будет добавлено к final_list. Однако, поскольку следующие 4 элемента - это [5, 5, 5, 6], они не будут добавлены.
Решения будут [5, 16, 34, 42]
Проблема, с которой я постоянно сталкиваюсь, заключается в том, что list index out of range.
Мой подход был:
for i in range(len(index_max)):
x = index_max[i]==index_max[i+(pattern_width)
final_list.append(x)
Однако это не работает в конце списка. Как мне это исправить? Спасибо.






Вы можете попробовать следующее
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
pattern_width = 4
final_list = []
for i in range(len(index_max) - pattern_width):
temp = index_max[i:i + pattern_width]
s = set(temp)
if len(s) == 1:
final_list.append(temp[0])
print(final_list) # Output [5, 16, 34, 42]
Рабочий пример https://ideone.com/Rz2gbK
Попробуй это :
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
pattern_width = 4
final_list = []
for i in range(len(index_max)-3):
count = 1
for j in range(pattern_width):
if index_max[i] == index_max[i+j]:
count += 1
if count == 4:
final_list.append(index_max[i])
print(final_list)
Если список всегда отсортирован, просто count для каждого значения:
final_list = [candidate for candidate in set(index_max) if index_max.count(candidate) >= pattern_width]
Поскольку большинство вызовов относятся к встроенным функциям, это должно быть достаточно быстрым.
Если вам нужны настоящие окна, внесите два изменения в свой подход:
pattern_width перед концом.Используйте set для идентификации уникальных окон.
# stop iteration ``pattern_width`` elements before the end
for i in range(len(index_max) - pattern_width):
# slice the window from the list and eliminate duplicates
window_elements = set(index_max[i:i+pattern_width])
if len(window_elements) == 1:
final_list.extend(window_elements)
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
n = 4
final_list = [index_max[i] for i in range(len(index_max)-(n-1)) if len(set(index_max[i:i+n])) == 1]
Это должно помочь. Разбивая это,
index_max[i] возвращает значение индекса, если условия соблюдены.range(len(index_max)-(n-1)) - будет перебирать каждую комбинацию из 4 в списке. N-1 гарантирует, что список остановится на последней комбинации длины 4.len(set(index_max[i:i+n])) == 1 преобразует список тестов в набор. Это позволит вам оценить уникальные значения в зависимости от длины набора.Если вас беспокоят повторяющиеся значения в вашем списке, вы просто используете набор значений, как показано ниже,
final_list = {index_max[i] for i in range(len(index_max)-(n-1)) if len(set(index_max[i:i+n])) == 1}
Вот решение, использующее несколько методов из itertools. Я пошел дальше и разбил проблему на 3 части, чтобы, если вам нужно делать другие вещи с кодом, он был более гибким.
import itertools
index_max = [5, 5, 5, 5, 6, 7, 14, 15, 16, 16, 16, 16, 18, 18, 32, 32, 34, 34, 34, 34, 35, 38, 42, 42, 42, 42, 45]
n = 4
def all_equal(iterable):
g = itertools.groupby(iterable)
return next(g, True) and not next(g, False)
def window(iterable, window_size):
iters = itertools.tee(iterable, window_size)
for i in range(1, window_size):
for it in iters[i:]:
next(it, None)
return zip(*iters)
def uniques_from_window(iterable, window_size):
return [sub_list[0] for sub_list in window(iterable, window_size) if all_equal(sub_list)]
print(uniques_from_window(index_max, n))
выходы
[5, 16, 34, 42]
Список всегда отсортирован?