Один из способов решения этой задачи — использовать словарь. Можно создать словарь, в котором каждому элементу списка соответствует количество его повторений, и в цикле перебрать элементы списка, добавляя их в словарь.
Вот пример такой функции:
def count_repeats(lst):
"""
Возвращает словарь, в котором каждому элементу списка lst соответствует
количество его повторений.
"""
repeats = {}
for item in lst:
if item in repeats:
repeats[item] += 1
else:
repeats[item] = 1
return repeats
# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
repeats = count_repeats(lst)
print(repeats) # {10: 3, 123: 2}
Функция count_repeats
принимает на вход список lst
, перебирает его элементы и добавляет их в словарь repeats
. Если элемент уже есть в словаре, то увеличивается значение соответствующей пары ключ-значение, если же элемента еще нет в словаре, то добавляется пара с ключом равным этому элементу и значением 1
.
Вы можете использовать эту функцию, чтобы найти повторяющиеся элементы в списке и количество их повторений.
Вы также можете использовать функцию Counter из модуля collections, чтобы посчитать количество повторений элементов списка. Эта функция возвращает словарь, в котором каждому элементу списка соответствует количество его повторений.
Вот пример кода, который использует функцию Counter:
from collections import Counter
def count_repeats(lst):
"""
Возвращает словарь, в котором каждому элементу списка lst соответствует
количество его повторений.
"""
return Counter(lst)
# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
repeats = count_repeats(lst)
print(repeats) # Counter({10: 3, 123: 2})
В этом коде сначала импортируется модуль collections
и функция Counter
, а затем определяется функция count_repeats
, которая принимает список lst
и возвращает результат вызова функции Counter
на этом списке.
Вы также можете использовать функцию most_common
из модуля collections
, чтобы найти топ-N самых часто встречающихся элементов в списке. Эта функция принимает список и число N, и возвращает список кортежей, каждый из которых содержит элемент и количество его повторений.
Вот пример кода, который использует функцию most_common
:
from collections import Counter
def find_top_repeats(lst, n):
"""
Возвращает топ-N самых часто встречающихся элементов в списке lst.
"""
return Counter(lst).most_common(n)
# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
top_repeats = find_top_repeats(lst, 2)
print(top_repeats) # [(10, 3), (123, 2)]
В этом коде сначала импортируется модуль collections
и функция Counter
, а затем определяется функция find_top_repeats
, которая принимает список lst
и число n
, и возвращает результат вызова функции most_common
Если вам нужно найти только уникальные элементы в списке, то можете использовать функцию set. Эта функция создает множество из элементов списка, удаляя повторяющиеся элементы. Множество не содержит повторяющихся элементов, поэтому вы можете использовать его, чтобы найти уникальные элементы в списке.
Вот пример кода, который использует функцию set
:
def find_unique(lst):
"""
Возвращает список уникальных элементов в списке lst.
"""
return list(set(lst))
# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
unique = find_unique(lst)
print(unique) # [66, 78, 10, 123, 23]
В этом коде определяется функция find_unique
, которая принимает список lst
и возвращает список уникальных элементов. Для этого список преобразуется в множество
Если вам нужно найти только уникальные элементы в списке и посчитать их количество, то можете соединить два предыдущих подхода: сначала использовать функцию set
для нахождения уникальных элементов, а затем функцию count_repeats
для подсчета их количества.
Вот пример кода, который реализует этот подход:
def count_unique(lst):
"""
Возвращает словарь, в котором каждому уникальному элементу списка lst соответствует
количество его повторений.
"""
repeats = {}
for item in set(lst):
repeats[item] = lst.count(item)
return repeats
# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
unique_counts = count_unique(lst)
print(unique_counts) # {66: 1, 78: 1, 10: 3, 123: 2}
В этом коде определяется функция count_unique
, которая принимает список lst
и возвращает словарь, в котором каждому уникальному элементу списка
Create a generator
Generators are fast and use a tiny memory footprint. They give you flexibility in how you use the result.
def indices(iter, val):
"""Generator: Returns all indices of val in iter
Raises a ValueError if no val does not occur in iter
Passes on the AttributeError if iter does not have an index method (e.g. is a set)
"""
i = -1
NotFound = False
while not NotFound:
try:
i = iter.index(val, i+1)
except ValueError:
NotFound = True
else:
yield i
if i == -1:
raise ValueError("No occurrences of {v} in {i}".format(v = val, i = iter))
The above code can be use to create a list of the indices: list(indices(input,value))
; use them as dictionary keys: dict(indices(input,value))
; sum them: sum(indices(input,value))
; in a for loop for index_ in indices(input,value):
; …etc… without creating an interim list/tuple or similar.
In a for loop you will get your next index back when you call for it, without waiting for all the others to be calculated first. That means: if you break out of the loop for some reason you save the time needed to find indices you never needed.
How it works
- Call
.index
on the inputiter
to find the next occurrence of
val
- Use the second parameter to
.index
to start at the point
after the last found occurrence - Yield the index
- Repeat until
index
raises aValueError
Alternative versions
I tried four different versions for flow control; two EAFP (using try - except
) and two TBYL (with a logical test in the while
statement):
- «WhileTrueBreak»:
while True:
…except ValueError: break
. Surprisingly, this was usually a touch slower than option 2 and (IMV) less readable - «WhileErrFalse»: Using a bool variable
err
to identify when aValueError
is raised. This is generally the fastest and more readable than 1 - «RemainingSlice»: Check whether val is in the remaining part of the input using slicing:
while val in iter[i:]
. Unsurprisingly, this does not scale well - «LastOccurrence»: Check first where the last occurrence is, keep going
while i < last
The overall performance differences between 1,2 and 4 are negligible, so it comes down to personal style and preference. Given that .index
uses ValueError
to let you know it didn’t find anything, rather than e.g. returning None
, an EAFP-approach seems fitting to me.
Here are the 4 code variants and results from timeit
(in milliseconds) for different lengths of input and sparsity of matches
@version("WhileTrueBreak", versions)
def indices2(iter, val):
i = -1
while True:
try:
i = iter.index(val, i+1)
except ValueError:
break
else:
yield i
@version("WhileErrFalse", versions)
def indices5(iter, val):
i = -1
err = False
while not err:
try:
i = iter.index(val, i+1)
except ValueError:
err = True
else:
yield i
@version("RemainingSlice", versions)
def indices1(iter, val):
i = 0
while val in iter[i:]:
i = iter.index(val, i)
yield i
i += 1
@version("LastOccurrence", versions)
def indices4(iter,val):
i = 0
last = len(iter) - tuple(reversed(iter)).index(val)
while i < last:
i = iter.index(val, i)
yield i
i += 1
Length: 100, Ocurrences: 4.0%
{'WhileTrueBreak': 0.0074799987487494946, 'WhileErrFalse': 0.006440002471208572, 'RemainingSlice': 0.01221001148223877, 'LastOccurrence': 0.00801000278443098}
Length: 1000, Ocurrences: 1.2%
{'WhileTrueBreak': 0.03101000329479575, 'WhileErrFalse': 0.0278000021353364, 'RemainingSlice': 0.08278000168502331, 'LastOccurrence': 0.03986000083386898}
Length: 10000, Ocurrences: 2.05%
{'WhileTrueBreak': 0.18062000162899494, 'WhileErrFalse': 0.1810499932616949, 'RemainingSlice': 2.9145700042136014, 'LastOccurrence': 0.2049500006251037}
Length: 100000, Ocurrences: 1.977%
{'WhileTrueBreak': 1.9361200043931603, 'WhileErrFalse': 1.7280600033700466, 'RemainingSlice': 254.4725100044161, 'LastOccurrence': 1.9101499929092824}
Length: 100000, Ocurrences: 9.873%
{'WhileTrueBreak': 2.832529996521771, 'WhileErrFalse': 2.9984100023284554, 'RemainingSlice': 1132.4922299943864, 'LastOccurrence': 2.6660699979402125}
Length: 100000, Ocurrences: 25.058%
{'WhileTrueBreak': 5.119729996658862, 'WhileErrFalse': 5.2082200068980455, 'RemainingSlice': 2443.0577100021765, 'LastOccurrence': 4.75954000139609}
Length: 100000, Ocurrences: 49.698%
{'WhileTrueBreak': 9.372120001353323, 'WhileErrFalse': 8.447749994229525, 'RemainingSlice': 5042.717969999649, 'LastOccurrence': 8.050809998530895}
В этом посте мы обсудим, как найти повторяющиеся элементы в списке в Python.
1. Использование index()
функция
Простое решение состоит в том, чтобы выполнить итерацию по списку с индексами, используя понимание списка, и проверить наличие другого вхождения каждого встреченного элемента, используя index()
функция. Временная сложность этого решения будет квадратичной, а код не обрабатывает повторяющиеся элементы в выводе.
if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] dup = [x for i, x in enumerate(nums) if i != nums.index(x)] print(dup) # [1, 5, 1] |
Скачать Выполнить код
2. Использование оператора In
Кроме того, вы можете использовать нарезку с in
оператор для поиска в уже посещенной части списка. Временная сложность решения остается квадратичной и позволяет повторять элементы на выходе.
if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] dup = [x for i, x in enumerate(nums) if x in nums[:i]] print(dup) # [1, 5, 1] |
Скачать Выполнить код
3. Использование набора (эффективно)
Чтобы повысить производительность и выполнить работу за линейное время, вы можете использовать set
структура данных.
if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] visited = set() dup = [x for x in nums if x in visited or (visited.add(x) or False)] print(dup) # [1, 5, 1] |
Скачать Выполнить код
Чтобы получить каждый дубликат только один раз, вы можете использовать понимание множества, как показано ниже:
if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] visited = set() dup = {x for x in nums if x in visited or (visited.add(x) or False)} print(dup) # {1, 5} |
Скачать Выполнить код
4. Использование count()
функция
Вот альтернативное решение с использованием count()
Функция, которая обеспечивает простой и понятный способ выявления дубликатов в списке. Это не рекомендуется для больших списков, поскольку временная сложность является квадратичной.
if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] dup = {x for x in nums if nums.count(x) > 1} print(dup) # {1, 5} |
Скачать Выполнить код
5. Использование iteration_utilities
модуль
Наконец, iteration_utilities
модуль предлагает duplicates
функция, которая дает повторяющиеся элементы. Вы можете использовать это как:
from iteration_utilities import duplicates if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] dup = list(duplicates(nums)) print(dup) # [1, 5, 1] |
Чтобы получить каждый дубликат только один раз, объедините его с unique_everseen()
:
from iteration_utilities import unique_everseen if __name__ == ‘__main__’: nums = [1, 5, 2, 1, 4, 5, 1] dup = unique_everseen(duplicates(nums)) print(dup) # [1, 5] |
Это все, что касается поиска повторяющихся элементов в списке в Python.
Также см:
Удалить повторяющиеся значения из списка Python
Чтобы найти уникальные элементы списка, вы можете воспользоваться набором в Python или использовать цикл for и перебирать, чтобы проверить, является ли элемент уникальным или нет.
Элемент считается уникальным, если он встречался в списке только один раз.
В этом руководстве мы напишем примеры программ, которые помогут нам найти уникальные элементы списка.
Пример 1: с помощью набора
Список в Python – это упорядоченный набор элементов, с разрешенными дубликатами.
Set – это набор уникальных элементов. Мы можем использовать это свойство, чтобы получить только уникальные элементы списка.
Передайте список в качестве аргумента конструктору набора, и он вернет набор уникальных элементов.
В следующей программе мы возьмем список чисел и создадим из него набор с помощью конструктора набора.
myList = [9, 1, 5, 9, 4, 2, 7, 2, 9, 5, 3] mySet = set(myList) print(mySet)
Вывод:
{1, 2, 3, 4, 5, 7, 9}
В получившийся набор попали только уникальные элементы.
Пример 2: с помощью цикла For Loop
Мы также можем использовать оператор цикла, например While Loop или For Loop, для перебора элементов списка и проверки того, появился ли элемент только один раз.
В следующей программе мы будем использовать вложенный цикл for, который предназначен для проверки уникальности каждого элемента. Внутренний цикл for предназначен для сравнения этого элемента с собранными уникальными элементами.
Алгоритм:
- Прочтите или возьмите список myList.
- Инициализируйте пустой список uniqueList.
- Для каждого элемента:
- Предположим, что этого элемента нет в myList – инициализировать itemExist значением False.
- Для каждого элемента x в uniqueList:
- Проверьте, равен ли элемент x. Если да, то этот элемент уже есть в вашем uniqueList. Установите для itemExist значение True и прервите цикл.
- Если itemExist имеет значение False, добавьте элемент в uniqueList.
- uniqueList содержит уникальные элементы myList:
- Предположим, что этого элемента нет в myList – инициализировать itemExist значением False.
- Для каждого элемента x в uniqueList:
- Проверьте, равен ли элемент x. Если да, то этот элемент уже есть в вашем uniqueList. Установите для itemExist значение True и прервите цикл.
- Если itemExist имеет значение False, добавьте элемент в uniqueList.
- Проверьте, равен ли элемент x. Если да, то этот элемент уже есть в вашем uniqueList. Установите для itemExist значение True и прервите цикл.
myList = [9, 1, 5, 9, 4, 2, 7, 2, 9, 5, 3] uniqueList = [] for item in myList : itemExist = False for x in uniqueList : if x == item : itemExist = True break if not itemExist : uniqueList.append(item) print(uniqueList)
Вывод:
[9, 1, 5, 4, 2, 7, 3]
Преимущество этого процесса в том, что порядок уникальных элементов не меняется.
Поиск повторяющихся элементов в списке
Чтобы найти только повторяющиеся элементы в списке в Python, вы можете проверить вхождения каждого элемента в списке и добавить его в дубликаты, если количество вхождений этого элемента больше одного.
Элемент считается дублированным, если он встречается в списке более одного раза.
В этом руководстве мы напишем примеры программ, которые помогут нам найти повторяющиеся элементы в списке.
Пример 1
В следующей программе мы возьмем список чисел и создадим из него набор с помощью конструктора набора.
myList = [9, 1, 5, 9, 4, 2, 7, 2, 9, 5, 3] occurrences = [] for item in myList : count = 0 for x in myList : if x == item : count += 1 occurrences.append(count) duplicates = set() index = 0 while index < len(myList) : if occurrences[index] != 1 : duplicates.add(myList[index]) index += 1 print(duplicates)
Вывод:
{9, 2, 5}
В результирующий набор попали только повторяющиеся элементы.
This div height required for enabling the sticky sidebar
Содержание
- Введение
- Поиск одинаковых элементов в списке с помощью словаря
- Поиск одинаковых элементов в списке с помощью модуля collections
- Поиск одинаковых элементов в списке с помощью функции filter()
- Заключение
Введение
В данной статье разберём три способа нахождения повторяющихся элементов в неупорядоченном списке Python.
Поиск одинаковых элементов в списке с помощью словаря
Для начала создадим неупорядоченный список с числами и пустой словарь:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
duplicate_elements = {}
Теперь пройдёмся по нашему неупорядоченному списку при помощи цикла for. Внутри цикла добавим условие, что если итерабельный элемент присутствует в словаре duplicate_elements, то прибавляем к значению ключа единицу, т.к. этот элемент уже присутствует в словаре, и был найден его дубликат. Если же условие оказалось ложным, то сработает else, где в словарь будет добавляться новый ключ, которого в нём ранее не было:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
duplicate_elements = {}
for item in unordered_list:
if item in duplicate_elements:
duplicate_elements[item] += 1
else:
duplicate_elements[item] = 1
Выведем результат:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
duplicate_elements = {}
for item in unordered_list:
if item in duplicate_elements:
duplicate_elements[item] += 1
else:
duplicate_elements[item] = 1
print(duplicate_elements)
# Вывод: {6: 2, 8: 1, 7: 2, 5: 2, 1: 1, 4: 2}
В выводе мы видим, что было найдено две шестёрки, одна восьмёрка, две семёрки, две пятёрки, одна единица и две четвёрки.
Поиск одинаковых элементов в списке с помощью модуля collections
В данном способе для поиска одинаковых элементов в неупорядоченном списке мы будем использовать модуль collections, а точнее класс Counter из него. Сам модуль входит в стандартную библиотеку Python, поэтому устанавливать его не придётся.
Для начала импортируем сам модуль collections и добавим неупорядоченный список:
import collections
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
Далее при помощи класса Counter из модуля collections подсчитаем количество повторяющихся элементов:
import collections
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
count_frequency = collections.Counter(unordered_list)
Выведем результат в виде словаря:
import collections
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
count_frequency = collections.Counter(unordered_list)
print(dict(count_frequency))
# Вывод: {6: 2, 8: 1, 7: 2, 5: 2, 1: 1, 4: 2}
Поиск одинаковых элементов в списке с помощью функции filter()
В данном способе мы просто будем выводить повторяющиеся элементы в списке, но не указывать количество их повторений.
При помощи функции filter() отфильтруем наш список. Внутри неё анонимной функцией lambda будем производить проверку поэлементно, и если определённый элемент встречается больше одного раза, мы добавляем его в count_frequency:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
count_frequency = filter(lambda x: unordered_list.count(x) > 1, unordered_list)
При помощи функции set() преобразуем полученные данные в count_frequency в множество, а множество в список:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
count_frequency = filter(lambda x: unordered_list.count(x) > 1, unordered_list)
count_frequency = list(set(count_frequency))
Выведем полученный результат:
unordered_list = [6, 6, 8, 7, 5, 1, 4, 5, 4, 7]
count_frequency = filter(lambda x: unordered_list.count(x) > 1, unordered_list)
count_frequency = list(set(count_frequency))
print(count_frequency)
# Вывод: [4, 5, 6, 7]
Т.е. в неупорядоченном списке повторяются четвёрки, пятёрки, шестёрки и семёрки.
Заключение
В ходе статьи мы с Вами разобрали целых три способа нахождения повторяющихся элементов в списке Python. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂