Предположим, есть список, который содержит повторяющиеся числа:
numbers = [1, 1, 2, 3, 3, 4]
Но нужен список с уникальными числами:
numbers = [1, 2, 3, 4]
Есть несколько вариантов, как можно получить уникальные значения. Разберем их.
Вариант №1. Использование множества (set) для получения элементов
Использование множества (set
) — один из вариантов. Он удобен тем, что включает только уникальные элементы. После этого множество можно обратно превратить в список.
Посмотрим на два способа использования множества и списка. Первый — достаточно подробный, но он позволяет увидеть происходящее на каждом этапе.
numbers = [1, 2, 2, 3, 3, 4, 5]
def get_unique_numbers(numbers):
list_of_unique_numbers = []
unique_numbers = set(numbers)
for number in unique_numbers:
list_of_unique_numbers.append(number)
return list_of_unique_numbers
print(get_unique_numbers(numbers))
Разберем, что происходит на каждом этапе. Есть список чисел numbers
. Передаем его в функцию get_unique_numbers
.
Внутри этой функции создается пустой список, который в итоге будет включать все уникальные числа. После этого используется set
для получения уникальных чисел из списка numbers
.
unique_numbers = set(numbers)
В итоге имеется перечень из уникальных чисел. Осталось сделать из него список. Для этого можно использовать цикл, перебирая каждый из элементов.
for number in unique_numbers:
list_of_unique_numbers.append(number)
На каждой итерации текущее число добавляется в список list_of_unique_numbers
. Наконец, именно этот список возвращается в конце программы.
Есть и более короткий способ использования множества для получения уникальных значений в Python. О нем и пойдет речь дальше.
Короткий вариант с set
Весь код выше можно сжать в одну строку с помощью встроенных в Python функций.
numbers = [1, 2, 2, 3, 3, 4, 5]
unique_numbers = list(set(numbers))
print(unique_numbers)
Хотя этот код сильно отличается от первого примера, идея та же. Сперва множество используется для получения уникальных значений. После этого множество превращается в список.
unique_numbers = list(set(numbers))
Проще всего думать «изнутри наружу» при чтении этого кода. Самый вложенный код выполняется первым: set(numbers)
. Затем — внешний блок: list(set(numbers))
.
Вариант №2. Использование цикла for
Также стоит рассмотреть подход с использованием цикла.
Для начала нужно создать пустой список, который будет включать уникальные числа. После этого можно задействовать цикл для итерации по каждому числу в переданном списке. Если число из него есть в уникальном, то можно переходить к следующему элементу. В противном случае — добавить это число.
Рассмотрим два способа использования цикла. Начнем с более подробного.
numbers = [20, 20, 30, 30, 40]
def get_unique_numbers(numbers):
unique = []
for number in numbers:
if number in unique:
continue
else:
unique.append(number)
return unique
print(get_unique_numbers(numbers))
Вот что происходит на каждом этапе. Сначала есть список чисел numbers
. Он передается в функцию get_unique_numbers
.
Внутри этой функции создается пустой список unique
. В итоге он будет включать все уникальные значения.
Цикл будет использоваться для перебора по числам в списке numbers
.
for number in numbers:
if number in unique:
continue
else:
unique.append(number)
Условные конструкции в цикле проверяют, есть ли число текущей итерации в списке unique
. Если да, то цикл переходит на следующую итерации. Если нет — число добавляется в список.
Важно отметить, что добавляются только уникальные числа. Когда цикл завершен, список unique
с уникальными числами возвращается.
Короткий способ с циклом
Есть и другой способ использования варианта с циклом, который короче на несколько строк.
numbers = [20, 20, 30, 30, 40]
def get_unique_numbers(numbers):
unique = []
for number in numbers:
if number not in unique:
unique.append(number)
return unique
Разница в условной конструкции. В этот раз она следующая — если числа нет в unique
, то его нужно добавить.
if number not in unique:
unique.append(number)
В противном случае цикл перейдет к следующему числу в списке numbers
.
Результат будет тот же. Но иногда подобное читать сложнее, когда булево значение опускается.
Есть еще несколько способов поиска уникальных значений в списке Python. Но достаточно будет тех, которые описаны в этой статье.
В этой статье мы рассмотрим 3 способа получения уникальных значений из списка в Python. Имея дело с огромным количеством необработанных данных, мы часто сталкиваемся с ситуациями, когда нам нужно извлечь уникальный и неповторяющийся набор данных из необработанного набора входных данных.
Для получения уникальных значений из списка в Python можно использовать любой из следующих способов:
- Метод set();
- Использование метода list.append() вместе с циклом for;
- Использование метода Python numpy.unique().
Содержание
- Set() для получения уникальных значений из списка
- list.append() и цикл for
- numpy.unique() для создания списка с уникальными элементами
Set() для получения уникальных значений из списка
Set хранит в себе одну копию повторяющихся значений. Это свойство можно использовать для получения уникальных значений из списка в Python.
- Первоначально нам нужно будет преобразовать список ввода в набор с помощью функции set().
Синтаксис:
set(input_list_name)
- Когда список преобразуется в набор, в него помещается только одна копия всех повторяющихся элементов.
- Затем нам нужно будет преобразовать набор обратно в список, используя следующую команду:
Синтаксис:
list(set-name)
- Наконец, распечатайте новый список. Пример:
list_inp = [100, 75, 100, 20, 75, 12, 75, 25] set_res = set(list_inp) print("The unique elements of the input list using set():n") list_res = (list(set_res)) for item in list_res: print(item)
Вывод:
The unique elements of the input list using set(): 25 75 100 20 12
list.append() и цикл for
Чтобы найти уникальные элементы, мы можем применить цикл Python for вместе с функцией list.append(), чтобы добиться того же:
- Сначала мы создаем новый (пустой) список, т.е. res_list.
- После этого, используя цикл for, мы проверяем наличие определенного элемента в новом созданном списке (res_list). Если элемент отсутствует, он добавляется в новый список с помощью метода append().
Синтаксис:
list.append(value)
В случае, если при обходе мы сталкиваемся с элементом, который уже существует в новом списке, то есть повторяющимся элементом, в этом случае он игнорируется циклом for. Мы будем использовать оператор if, чтобы проверить, является ли этот элемент уникальным или повторяющимся.
Пример:
list_inp = [100, 75, 100, 20, 75, 12, 75, 25] res_list = [] for item in list_inp: if item not in res_list: res_list.append(item) print("Unique elements of the list using append():n") for item in res_list: print(item)
Вывод:
Unique elements of the list using append(): 100 75 20 12 25
numpy.unique() для создания списка с уникальными элементами
Модуль NumPy имеет встроенную функцию с именем numpy.unique для извлечения уникальных элементов данных из массива numpy.
Чтобы получить уникальные элементы из списка Python, нам нужно будет преобразовать список в массив NumPy, используя следующую команду.
Синтаксис:
numpy.array(list-name)
Затем мы будем использовать метод numpy.unique() для извлечения уникальных элементов данных из массива numpy и, наконец, распечатаем получившийся список.
Синтаксис:
numpy.unique(numpy-array-name)
Пример:
import numpy as N list_inp = [100, 75, 100, 20, 75, 12, 75, 25] res = N.array(list_inp) unique_res = N.unique(res) print("Unique elements of the list using numpy.unique():n") print(unique_res)
Вывод:
Unique elements of the list using numpy.unique(): [12 20 25 75 100]
( 9 оценок, среднее 3 из 5 )
Помогаю в изучении Питона на примерах. Автор практических задач с детальным разбором их решений.
If we need to keep the elements order, how about this:
used = set()
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for x in mylist if x not in used and (used.add(x) or True)]
And one more solution using reduce
and without the temporary used
var.
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])
UPDATE – Dec, 2020 – Maybe the best approach!
Starting from python 3.7, the standard dict preserves insertion order.
Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.
So this gives us the ability to use dict.from_keys
for de-duplication!
NOTE: Credits goes to @rlat for giving us this approach in the comments!
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = list(dict.fromkeys(mylist))
In terms of speed – for me its fast enough and readable enough to become my new favorite approach!
UPDATE – March, 2019
And a 3rd solution, which is a neat one, but kind of slow since .index
is O(n).
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for i, x in enumerate(mylist) if i == mylist.index(x)]
UPDATE – Oct, 2016
Another solution with reduce
, but this time without .append
which makes it more human readable and easier to understand.
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])
#which can also be writed as:
unique = reduce(lambda l, x: l if x in l else l+[x], mylist, [])
NOTE: Have in mind that more human-readable we get, more unperformant the script is. Except only for the dict.from_keys
approach which is python 3.7+ specific.
import timeit
setup = "mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']"
#10x to Michael for pointing out that we can get faster with set()
timeit.timeit('[x for x in mylist if x not in used and (used.add(x) or True)]', setup='used = set();'+setup)
0.2029558869980974
timeit.timeit('[x for x in mylist if x not in used and (used.append(x) or True)]', setup='used = [];'+setup)
0.28999493700030143
# 10x to rlat for suggesting this approach!
timeit.timeit('list(dict.fromkeys(mylist))', setup=setup)
0.31227896199925453
timeit.timeit('reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7149233570016804
timeit.timeit('reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7379565160008497
timeit.timeit('reduce(lambda l, x: l if x in l else l+[x], mylist, [])', setup='from functools import reduce;'+setup)
0.7400134069976048
timeit.timeit('[x for i, x in enumerate(mylist) if i == mylist.index(x)]', setup=setup)
0.9154880290006986
ANSWERING COMMENTS
Because @monica asked a good question about “how is this working?”. For everyone having problems figuring it out. I will try to give a more deep explanation about how this works and what sorcery is happening here 😉
So she first asked:
I try to understand why
unique = [used.append(x) for x in mylist if x not in used]
is not working.
Well it’s actually working
>>> used = []
>>> mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
>>> unique = [used.append(x) for x in mylist if x not in used]
>>> print used
[u'nowplaying', u'PBS', u'job', u'debate', u'thenandnow']
>>> print unique
[None, None, None, None, None]
The problem is that we are just not getting the desired results inside the unique
variable, but only inside the used
variable. This is because during the list comprehension .append
modifies the used
variable and returns None
.
So in order to get the results into the unique
variable, and still use the same logic with .append(x) if x not in used
, we need to move this .append
call on the right side of the list comprehension and just return x
on the left side.
But if we are too naive and just go with:
>>> unique = [x for x in mylist if x not in used and used.append(x)]
>>> print unique
[]
We will get nothing in return.
Again, this is because the .append
method returns None
, and it this gives on our logical expression the following look:
x not in used and None
This will basically always:
- evaluates to
False
whenx
is inused
, - evaluates to
None
whenx
is not inused
.
And in both cases (False
/None
), this will be treated as falsy
value and we will get an empty list as a result.
But why this evaluates to None
when x
is not in used
? Someone may ask.
Well it’s because this is how Python’s short-circuit operators works.
The expression
x and y
first evaluates x; if x is false, its value is
returned; otherwise, y is evaluated and the resulting value is
returned.
So when x
is not in used (i.e. when its True
) the next part or the expression will be evaluated (used.append(x)
) and its value (None
) will be returned.
But that’s what we want in order to get the unique elements from a list with duplicates, we want to .append
them into a new list only when we they came across for a fist time.
So we really want to evaluate used.append(x)
only when x
is not in used
, maybe if there is a way to turn this None
value into a truthy
one we will be fine, right?
Well, yes and here is where the 2nd type of short-circuit
operators come to play.
The expression
x or y
first evaluates x; if x is true, its value is
returned; otherwise, y is evaluated and the resulting value is
returned.
We know that .append(x)
will always be falsy
, so if we just add one or
next to him, we will always get the next part. That’s why we write:
x not in used and (used.append(x) or True)
so we can evaluate used.append(x)
and get True
as a result, only when the first part of the expression (x not in used)
is True
.
Similar fashion can be seen in the 2nd approach with the reduce
method.
(l.append(x) or l) if x not in l else l
#similar as the above, but maybe more readable
#we return l unchanged when x is in l
#we append x to l and return l when x is not in l
l if x in l else (l.append(x) or l)
where we:
- Append
x
tol
and return thatl
whenx
is not inl
. Thanks to theor
statement.append
is evaluated andl
is returned after that. - Return
l
untouched whenx
is inl
Given a list, print all the unique numbers in any order.
Examples:
Input : 10 20 10 30 40 40
Output : 10 20 30 40Input : 1 2 1 1 3 4 3 3 5
Output : 1 2 3 4 5
Method 1: Traversal of the list
Using traversal, we can traverse for every element in the list and check if the element is in the unique_list already if it is not over there, then we can append it to the unique_list. This is done using one for loop and another if statement which checks if the value is in the unique list or not which is equivalent to another for a loop.
Python
def
unique(list1):
unique_list
=
[]
for
x
in
list1:
if
x
not
in
unique_list:
unique_list.append(x)
for
x
in
unique_list:
print
x,
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output
the unique values from 1st list is 10 20 30 40 the unique values from 2nd list is 1 2 3 4 5
Time Complexity: O(n*n)
Auxiliary Space: O(n)
Method 2: Using Set
Using set() property of Python, we can easily check for the unique values. Insert the values of the list in a set. Set only stores a value once even if it is inserted more than once. After inserting all the values in the set by list_set=set(list1), convert this set to a list to print it.
Python
def
unique(list1):
list_set
=
set
(list1)
unique_list
=
(
list
(list_set))
for
x
in
unique_list:
print
x,
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output
the unique values from 1st list is 40 10 20 30 the unique values from 2nd list is 1 2 3 4 5
Time complexity: O(n), where n is length of list.
Auxiliary Space: O(n), where n is length of list.
Method 3: Using numpy.unique
Using Python’s import numpy, the unique elements in the array are also obtained. In the first step convert the list to x=numpy.array(list) and then use numpy.unique(x) function to get the unique values from the list. numpy.unique() returns only the unique values in the list.
Python3
import
numpy as np
def
unique(list1):
x
=
np.array(list1)
print
(np.unique(x))
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output:
the unique values from 1st list is [10 20 30 40] the unique values from 2nd list is [1 2 3 4 5]
Time complexity: O(nlogn) due to the use of the sorting algorithm used by the numpy.unique() function.
Auxiliary space: O(n) because numpy.unique() function creates a copy of the input array and then sorts it before returning the unique elements.
Method #4: Using collections.Counter()
Using python import Counter() from collections print all the keys of Counter elements or we print directly by using the “*” symbol. Below is the implementation of above approach.
Python3
from
collections
import
Counter
def
unique(list1):
print
(
*
Counter(list1))
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output
the unique values from 1st list is 10 20 30 40 the unique values from 2nd list is 1 2 3 4 5
Time Complexity: O(n), where n is the number of elements in the input list.
Auxiliary Space : O(n)
Method #5: Using reduce()
Using python import reduce() from functools and iterate over all element and checks if the element is a duplicate or unique value. Below is the implementation of the above approach.
Python
from
functools
import
reduce
def
unique(list1):
ans
=
reduce
(
lambda
re, x: re
+
[x]
if
x
not
in
re
else
re, list1, [])
print
(ans)
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output
the unique values from 1st list is [10, 20, 30, 40] the unique values from 2nd list is [1, 2, 3, 4, 5]
Method #6:Using Operator.countOf() method
Python3
import
operator as op
def
unique(list1):
unique_list
=
[]
for
x
in
list1:
if
op.countOf(unique_list, x)
=
=
0
:
unique_list.append(x)
for
x
in
unique_list:
print
(x)
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output
the unique values from 1st list is 10 20 30 40 the unique values from 2nd list is 1 2 3 4 5
Time Complexity:O(N)
Auxiliary Space: O(N)
Method#7: Using pandas
Python3
import
pandas as pd
def
unique(list1):
unique_list
=
pd.Series(list1).drop_duplicates().tolist()
for
x
in
unique_list:
print
(x)
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
print
(
"the unique values from 1st list is"
)
unique(list1)
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
print
(
"nthe unique values from 2nd list is"
)
unique(list2)
Output:
the unique values from 1st list is 10 20 30 40 the unique values from 2nd list is 1 2 3 4 5
Time Complexity:O(N)
Auxiliary Space: O(N)
Method #8: Using dict.fromkeys() –
Using the fromkeys() method of dictionary data structure we can fetch the unique elements.
Step – 1: Firstly we need to define a list which consists of duplicate elements.
Step – 2 : Then we need to use a variable in which we will store the result after using the fromkeys() method.
Step – 3 : We need to convert that result into list, as the fromkeys() method is part of the dictionary so by default it returns a dictionary with all the unique keys and None as their values.
Step – 4 : We will print the final result.
Python3
list1
=
[
10
,
20
,
10
,
30
,
40
,
40
]
list2
=
[
1
,
2
,
1
,
1
,
3
,
4
,
3
,
3
,
5
]
unique_list_1
=
list
(
dict
.fromkeys(list1))
unique_list_2
=
list
(
dict
.fromkeys(list2))
print
(unique_list_1,unique_list_2,sep
=
"n"
)
Output
[10, 20, 30, 40] [1, 2, 3, 4, 5]
Time Complexity – O(n)
Space Complexity – O(n)
Last Updated :
15 May, 2023
Like Article
Save Article
Say you have a list that contains duplicate numbers:
numbers = [1, 1, 2, 3, 3, 4]
But you want a list of unique numbers.
unique_numbers = [1, 2, 3, 4]
There are a few ways to get a list of unique values in Python. This article will show you how.
Option 1 – Using a Set to Get Unique Elements
Using a set
one way to go about it. A set is useful because it contains unique elements.
You can use a set to get the unique elements. Then, turn the set into a list.
Let’s look at two approaches that use a set and a list. The first approach is verbose, but it’s useful to see what’s happening each step of the way.
numbers = [1, 2, 2, 3, 3, 4, 5]
def get_unique_numbers(numbers):
list_of_unique_numbers = []
unique_numbers = set(numbers)
for number in unique_numbers:
list_of_unique_numbers.append(number)
return list_of_unique_numbers
print(get_unique_numbers(numbers))
# result: [1, 2, 3, 4, 5]
Let’s take a closer look at what’s happening. I’m given a list of numbers, numbers
. I pass this list into the function, get_unique_numbers
.
Inside the function, I create an empty list, which will eventually hold all of the unique numbers. Then, I use a set
to get the unique numbers from the numbers
list.
unique_numbers = set(numbers)
I have what I need: the unique numbers. Now I need to get these values into a list. To do so, I use a for loop to iterate through each number in the set.
for number in unique_numbers:
list_of_unique_numbers.append(number)
On each iteration I add the current number to the list, list_of_unique_numbers
. Finally, I return this list at the end of the program.
There’s a shorter way to use a set and list to get unique values in Python. That’s what we’ll tackle next.
A Shorter Approach with Set
All of the code written in the above example can be condensed into one line with the help of Python’s built-in functions.
numbers = [1, 2, 2, 3, 3, 4, 5]
unique_numbers = list(set(numbers))
print(unique_numbers)
# Result: [1, 2, 3, 4, 5]
Although this code looks very different from the first example, the idea is the same. Use a set to get the unique numbers. Then, turn the set into a list.
unique_numbers = list(set(numbers))
It’s helpful to think “inside out” when reading the above code. The innermost code gets evaluated first: set(numbers)
. Then, the outermost code is evaluated: list(set(numbers))
.
Option 2 – Using Iteration to Identify Unique Values
Iteration is another approach to consider.
The main idea is to create an empty list that’ll hold unique numbers. Then, use a for loop iterate over each number in the given list. If the number is already in the unique list, then continue on to the next iteration. Otherwise, add the number to it.
Let’s look at two ways to use iteration to get the unique values in a list, starting with the more verbose one.
numbers = [20, 20, 30, 30, 40]
def get_unique_numbers(numbers):
unique = []
for number in numbers:
if number in unique:
continue
else:
unique.append(number)
return unique
print(get_unique_numbers(numbers))
# Result: [20, 30, 40]
Here’s what’s happening each step of the way. First, I’m given a list of numbers, numbers
. I pass this list into my function, get_unique_numbers
.
Inside the function, I create an empty list, unique
. Eventually, this list will hold all of the unique numbers.
I use a for loop to iterate through each number in the numbers
list.
for number in numbers:
if number in unique:
continue
else:
unique.append(number)
The conditional inside the loop checks to see if the number of the current iteration is in the unique
list. If so, the loop continues to the next iteration. Otherwise, the number gets added to this list.
Here’s the important point: only the unique numbers are added. Once the loop is complete, then I return unique
which contains all of the unique numbers.
A Shorter Approach with Iteration
There’s another way to write the function in fewer lines.
numbers = [20, 20, 30, 30, 40]
def get_unique_numbers(numbers):
unique = []
for number in numbers:
if number not in unique:
unique.append(number)
return unique
#Result: [20, 30, 40]
The difference is the conditional. This time it’s set up to read like this: if the number is not in unique
, then add it.
if number not in unique:
unique.append(number)
Otherwise, the loop will move along to the next number in the list, numbers
.
The result is the same. However, it’s sometimes harder to think about and read code when the boolean is negated.
There are other ways to find unique values in a Python list. But you’ll probably find yourself reaching for one of the approaches covered in this article.
I write about learning to program, and the best ways to go about it on amymhaddad.com. Follow me on Twitter: @amymhaddad.
Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started