Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Вернуть массив, состоящий только из неуникальных элементов данного массива

#python #алгоритм #python_3x


def A(number) :

    for item in range(len(number)) :
        if number.count(item) < 2 : # определяю уникальный или нет
            number[item] *= 0       # превращаю уникальный в ноль

            for i, elem in enumerate(number) :
                if elem == 0 :
                    del number[i]    # если ноль - удаляю
                    return number


Дан непустой массив целых чисел. Нужно вернуть массив, состоящий только из неуникальных
элементов данного массива. Для этого необходимо удалить все уникальные элементы (которые
присутствуют в данном массиве только один раз). Нельзя менять оригинальный порядок
элементов.

Мой код работает, но убирает только первый уникальный элемент, а остальные не трогает.Почему,
не знаю, но хотел бы узнать.

Если дается [1, 2, 3, 3, 3] , то должно вернуться - [3, 3, 3]. А у меня возвращается
- [2, 3, 3, 3].
    


Ответы

Ответ 1



Вот в этом куске for i, elem in enumerate(number) : if elem == 0 : del number[i] # если ноль - удаляю Вы удаляете элементы из того списка, по которому итерируетесь. Так делать нельзя, иначе после удаления элемента цикл будет перескакивать через следующий элемент (потому что после удаления предыдущего он сдвинулся на его место). Поэтому некоторые элементы у вас и не удаляются - в цикле они просто проскальзывают мимо. Вообще, нужно стараться заменять циклы списковыми выражениями там, где это возможно. Например, вашу функцию можно написать в одну строчку: def A(number) : return [i for i in number if number.count(i) > 1]

Ответ 2



Линейный алгоритм по времени и памяти (O(n) - время, O(n) - память), который новый список возвращает, содержащий элементы, которые встречаются более одного раза, сохраняя порядок исходного списка: from collections import Counter def non_uniq(numbers): counter = Counter(numbers) return [n for n in numbers if counter[n] > 1] Пример из вопроса: >>> non_uniq([1, 2, 3, 3, 3]) [3, 3, 3] Если одинаковые элементы всегда рядом, можно однопроходный алгоритм, использующий только постоянную память (O(n) - время, O(1) - память): from itertools import groupby, islice def non_uniq_adjacent(sorted_numbers, min_repeat=2): for _, same in groupby(sorted_numbers): adjacent = list(islice(same, min_repeat)) if len(adjacent) == min_repeat: yield from adjacent yield from same Пример: >>> list(non_uniq_adjacent([1, 2, 3, 3, 3])) [3, 3, 3]

Ответ 3



collections.Counter from collections import Counter def A(numbers: list) -> list: '''Нужно вернуть массив, состоящий только из неуникальных элементов данного массива. Для этого необходимо удалить все уникальные элементы''' counter = Counter(numbers) unique = [n for n in counter if counter[n] == 1] # уникальные элементы for n in unique: # удалить все уникальные элементы numbers.remove(n) return numbers

Комментариев нет:

Отправить комментарий