Итерации по набору в Python

Опубликовано: 4 Февраля, 2022

В Python Set - это неупорядоченный набор типов данных, который является повторяемым, изменяемым и не имеет повторяющихся элементов.

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

Analysis of each method:
For explaining the working of each way/technique, time per set(randomly generated set) has been calculated for 5-times to get a rough estimate on how much time every technique takes for iterating over a given set. random.seed(21) has been added to each script to fixate over the random numbers that are generated every time the program is executed. Using constant seed helps us to determine which technique is best for a given particular randomly generated set.

Method #1: Iterating over a set using simple for loop.

# Creating a set using string
test_set = set("geEks")
  
# Iterating using for loop
for val in test_set:
    print(val)

Выход:

k
s
e
g
E

Analysis:

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    for val in test_set:
        _ = val
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
  
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход:

 0,06303901899809716
0,06756918999963091
0,06692574200133095
0,067220498000097
0,06748137499744189

Method #2: Iterating over a set using enumerated for loop.

# Creating a set using string
test_set = set("geEks")
  
# Iterating using enumerated for loop
for id,val in enumerate(test_set):
    print(id, val)

Выход:

 0 E
1 е
2 к
3 г
4 с

Analysis:

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    for id, val in enumerate(test_set):
        _ = val
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 0,1306622320007591
0,13657568199778325
0,13797824799985392
0,1386374360008631
0,1424286179972114


Метод № 3: Итерация по набору как индексированному списку.

Выход:

 грамм
k
E
s
е

Analysis:

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    test_list = list(test_set)
  
    for id in range(len(test_list)):
        _ = test_list[id]
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 0.20036015100049553
0,2557020290005312
0,4601482660000329
0,2161413249996258
0,18769703499856405

 
Method #4: Iterating over a set using comprehension and list constructor/initializer.

# Creating a set using string
test_set = set("geEks")
  
# Iterating using list-comprehension
com = list(val for val in test_set)
print(*com)

Выход:

 kseg E

Analysis:

# importing libraires
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    list(val for val in test_set)
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 0,1662169310002355
0,1783527520019561
0,21661155100082397
0,19131610199838178
0,19931397800246486

 
Method #5: Iterating over a set using comprehension.

# Creating a set using string
test_set = set("geEks")
  
# Iterating using list-comprehension
com = [print(val) for val in test_set]

Выход:

 е
E
грамм
s
k

Analysis:

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    [val for val in test_set]
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 0,11386321299869451
0,111869686999853
0,1092844699996931
0,11223735699968529
0,10928539399901638

 
Method #6: Iterating over a set using map, lambda and list comprehension

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    [map(lambda val: val, test_set)]
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 1.0756000847322866e-05
1.310199877480045e-05
1.269100175704807e-05
1.1588999768719077e-05
1.2522999895736575e-05

 
Method #7: Iterating over a set using iterator.

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    for val in iter(test_set):
        _ = val
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход :

 0,0676155920009478
0,07111633900058223
0,06994135700006154
0,0732101009998587
0,08668379899972933

Method #8: Iterating over a set using iterator and while loop.

# Creating a set using string
test_set = set("geEks")
  
iter_gen = iter(test_set)
  
while True:
    try:
        # get the next item
        print(next(iter_gen))
          
        """ do something with element """
          
    except StopIteration:
        # if StopIteration is raised,
        # break from loop
        break

Выход:

 E
s
е
k
грамм

Analysis:

# importing libraries
from timeit import default_timer as timer
import itertools
import random
  
# Function under evaluation
def test_func(test_set):
  
    iter_gen = iter(test_set)
    while True:
        try:
            # get the next item
            next(iter_gen)
            # do something with element
        except StopIteration:
            # if StopIteration is raised, break from loop
            break
  
# Driver function
if __name__ == "__main__":
  
    random.seed(21)
    for _ in range(5):
        test_set = set()
  
        # generating a set of random numbers
        for el in range(int(1e6)):
            el = random.random()
            test_set.add(el)
  
        start = timer()
        test_func(test_set)
        end = timer()
  
        print(str(end - start))

Выход:

 0,2136418699992646
0,1952157889973023
0,4234208280031453
0,255840524998348
0,24712910099697183

Заключение:
Среди всех методов цикла лучше всего работает простая итерация цикла и цикл по итераторам, в то время как при сравнении всех методов, использование map с лямбда над набором или итератор набора работает лучше всего, обеспечивая производительность в миллион итераций набора менее 10 миллисекунд. Довольно заметно, что в приведенных выше примерах имеется только один доступ к заданным компонентам на итерацию, тогда как если мы увеличим количество обращений к заданному компоненту за итерацию, это может изменить время, затрачиваемое на итерацию.

Примечание. Значения, упомянутые выше в выходных данных примера, обязательно должны изменяться. Причина изменения затрат времени - это машинная зависимость вычислительной мощности отдельного системного процессора.

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.