Skip to content

Latest commit

 

History

History
551 lines (380 loc) · 21.1 KB

File metadata and controls

551 lines (380 loc) · 21.1 KB

Разбираем вопросы по Python.


Чем поток отличается от процесса?

Потоки могут иметь доступ к области видимости друг друга, а процессы изолированы друг от друга.


Интерполяции строк - вставка данных в строку через скобочки, в питоне есть 3 способа интерполяции строк: f, %s, format.


Разница времени получения значений из списка и словаря

Для списка скорость O(n) - прямо как у списков.

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


Функция bin() дает бинарное значение числа

    print(bin(5))

    # Вывод
    # 0b101

Функция abs() дает абсолютное значение числа

    print(abs(2))
    print(abs(-2))

    # Вывод
    # 2
    # 2

Как отсортировать словарь по ключам, в алфавитном порядке? Функция sorted() вернет список из кортежей, делаем это и даже генерируем новый словарь используя полученные кортежи делая из них словари.

    d = {'c': 3, 'd': 4, 'b': 2, 'a': 1}
    print(d)
    
    d = {key:val for key, val in sorted(d.items())}
    print(d)

В чем разница между remove, del и pop ?

remove() - удаляет первое совпадающее значение.

del - удаляет элемент по его индексу

pop() - удаляет элемент по индексу и возвращает этот элемент, и удаляет последний элемент если индекс не был передан.


Что будет если превратить словарь в список ?

Мы получим список из ключей словаря.

    d = {'id': 7, 'name': 'Shiba', 'color': 'brown', 'speed': 'very slow'}
    print(list(d))

    # Вывод
    # ['id', 'name', 'color', 'speed']

Функция round

round - округляет в ближнею сторону, второй аргумент указывает до какого числа округлить.

    a = 12.1234567
    print(round(a,3))

    # Вывод
    # 12.123

Что сдлеает след код ?

    a = [1, 2, 3]
    b = a
    a.pop()
    b.pop()
    print(a == b == [1])

Отвтет True так как == проверяет по значению а не по ссылке, и a и b ссылаются на один обьект который является [1]


Существует 3 способа как перевернуть список

Метод reversed возвращает новый итерир обьект из списка и этот обьект перевернут, срез тоже создает новый список [::-1] но перевернутый в обратном порядке, и только .reverse() не создает нового обьекта, он переворачивает старый список, так что его перед этим стоит скопировать.

    reversed(list)
    list[::-1]
    list.reverse()

Как развернуть список ?

Из списка формата [[1, 2], [3, 4]] надо сделать список [1, 2, 3, 4]

    alist = [[1, 2], [3, 4]]
    new_list = [x for el in alist for x in el]
    print(new_list)

Линтеры.

В сообществе программистов есть так называемые хорошие практики для соблюд этих практик используют механизм Линтеров, это статические анализаторы кода которые помагают распозновать ошибки в программе.

Примеры Линтеров:

  1. flake8
  2. pylint

Цикломатическая сложность кода https://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C#:~:text=%D0%A6%D0%B8%D0%BA%D0%BB%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%CC%81%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F%20%D1%81%D0%BB%D0%BE%CC%81%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%CC%81%D0%BC%D0%BC%D1%8B%20(%D0%B0%D0%BD%D0%B3%D0%BB.%20cyclomatic,%D0%9C%D0%B5%D1%80%D0%B0%20%D0%B1%D1%8B%D0%BB%D0%B0%20%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%BD%D0%B0%20%D0%A2%D0%BE%D0%BC%D0%B0%D1%81%D0%BE%D0%BC%20%D0%94%D0%B6

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


Функция zip.

Эта функция хорошо применима в ситуации когда требуется слить 2 одиноковых по длинне списка, сделать ключами один из список в значения дуругова сделать значениями:

    keys = ['red', 'green', 'blue']
    values = ['#FF0000', '#008000', '#0000FF']
    res_dict = dict(zip(keys, values))
    print(res_dict)

    # Вывод
    # {'red': '#FF0000', 'green': '#008000', 'blue': '#0000FF'}

Сама функция zip возвращает некий обьект который треб в явном виде привести к словарю.


Совместная комбинация assert, all(), map(), lambda

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

      assert all(map(lambda i: i>0, new_params))
      self._params = new_params

assert - выдет ошибку AssertionError если значение его False, all() вернет этот False если хотябы одно из значений неверное, map() применяет функцию lambda к каждому элементу списка, и если хотябы один из елементов списка не проходит проверку то возвращатеся False

Так происходит проверка всех элементов списка, и если хоятбы один из списка не проходит проверку то получаем исключение.


В случае множественного наследования используется алгоритм С3 для определения метода который нужно вызвать, получить иерархию можно с помощью спец атрибута который есть у каждого обьекта __mro__.

Также можно использовать метод mro() он выдает тоже самое.


@property - некотрые атрибуты можно посчитать динамически из других атрибутов, подобные свойтсва вычисляются динамически каждый раз, кеширования у них нету, так образ мы создаем новое свойство из уже существующих.

@property - требует для своей работы чтобы атрибут который оно будет вычислять имеет модификатор доступа protected


Атрибут obj.__dict__ можно удалить вабще из вне, прсотым оператором del

      del np.__dict__
      np.__dict__

      # Вывод
      # {}

Удалить атрибут __dict__ можно удалить только у обьекта класса, у самого класса его удалить нельзя, мы получим ошибку.

  AttributeError: attribute '__dict__' of 'type' objects is not writable

Функция vars() выводит атрибуты что принадлежат обьекту, тоесть vars() и obj__dict__ выведут абсолютно одинаковые атрибуты.


.__base__ - атрибут класса укказывает класс родитель. .__bases__ - атрибут класса укказывает все классы родители в виде кортежа.


Функция id().

id(arg1) Принимает любой обьект и возвращает целочисленное значение которое будет служить указателем на ячейку в памяти.


Функция zip().

zip(arg1, arg2, arg3) Принимает в себя ряд последовательностей и возвращает обратно обьект который можно превратить в список, данная функция проходит по всем последовательностям и генерирует из них кортежи, генерация происходит по столбцам если выстроить списки в ряд, к примеру так:

    a = [1,2,3]
    b = "xyz"
    c = (None, True)
     
    res = list(zip(a, b, c))
    print (res)
   
    # Вывод
    # [(1, 'x', None), (2, 'y', True)]

Как видим генерация обрывается по самому короткому списку из всех.

Еще пример:

    list1 = [7,2,3,10,12]
    list2 = [-1,1,-5,4,6]

    zip_var = zip(list1, list2)
    gener_list = [ x*y for x, y in zip_var ]

    print(gener_list)

    # Вывод
    # [-7, 2, -15, 40, 72]

Найти квадрат и корень числа:

Найти квадрат можно 2 способами, либо импортировав модуль math и использовать его метод math.sqrt()

import math
print(math.sqrt(16))

Другой способ это использовать оператор возведения в степень ** но возвести в степень 0.5

print(16**0.5)

Возвести в корень можно просто оператором **:

print(4**2)

Развернуть строку, указываем два двоеточия дважды, что означает вывести все элементы строки, в конце указываем шаг -1 что означает вывести с шагом с последнего элемента до первого.

string[::-1]

Создать списки с тремя нулями 2 способами, можно просто обьявить список с тремя элементами [0,0,0]. Другой способ заключается в том чтобы создать список с одним элементом, и умножить на 3 [0]*3 этот метод создает список и дублирует его элементы указанное количество раз.

my_list1 = [0,0,0]
my_list2 = [0]*3

Вывести слово hello из словаря:

d = {'k1':[{'nest_key':['this is deep', ['hello']]}]}
print(d['k1'][0]['nest_key'][1][0])

Тут нет ничего сложного, просто надо следить и чередовать как индексы так и ключи.


Использовать множества чтобы найти уникальные значения в списке.

    l = [1,2,33,4,4,11,22,3,3,2]
    l = set(l)
    print(l)

Множества могут содержать только уникальные значения, также из список можно конвертировать в множество, так переведя список в множество, мы автоматически оставляем в множестве только уникальные значения.

У множест отсутствует метод .sort() для сортировки элементов, может прийти идея отсортировать список а потом перевести этот список в множество, что по идеи должно дать отсортированное множество.

Но это не работает, вот пример:

    l = [1, 2, 33, 4, 4, 11, 22, 3, 3, 2]
    l.sort()
    print(l)

    l = set(l)
    print(l)

    # Вывод
    # [1, 2, 2, 3, 3, 4, 4, 11, 22, 33]
    # {1, 2, 3, 4, 33, 11, 22}

тут можно увидеть что список действительно сортируется, но после перевода в множество, порядок элементов изменился.


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

Сделать это можно след кодом, через цикл for :

    string = "Hello Mr. Rogers, how are you this fine Tuesday?"    

    upp = 0
    low = 0
    other = 0

    for char in string:
        if char.isupper():
            upp += 1
        elif char.islower():
            low += 1
        else:
            other +=1

Нужно взять список с повторяющимися значениями, и вернуть список только с уникальными значениями:

    if type(in_list) is list and len(in_list) > 1 :
        return list(set(in_list))
    else:
        raise ValueError("Аргумент должен быть списком, 
        и иметь больше одного элемента.")

Мы имеем список, списки могут содержать повторяющиеся значения, а вот множества могут иметь только уникальные значения, так что переведя список в множество мы автоматически исключаем из него повторные значения, после переводим его обратно в список, и получаем список только с уникальными значениями.

Есть другой способ решения, он основан на просто переборе элементов, мы перебираем элементы списка на поиск совпадений с изначально пустым списком, и если элемент не найден то заносим значение в список, если найден, значит это повторяющийся элемент.

    result_list = []

    for elem in in_list:
        if elem not in result_list:
            result_list.append(elem)

    return result_list

Проверка строки на то является ли она панграммой - тоесть строка содержит все буквы алфавита, такие строки панграммы используются для проверки как выглядят все символы алфовита в разных шрифтах.

В питоне для этого используется модуль import string

В модуле string есть переменная ascii_lowercase которая содержит в себе все буквы алфавита.

  1. Первый способ:
    import string

    alphabet = string.ascii_lowercase
    print(alphabet)        

    # Вывод
    # abcdefghijklmnopqrstuvwxyz

Для проверки находится ли в строке все символы алфавита, сделаем такую программу:

    from string import ascii_lowercase as alphabet

    for char in alphabet:
        if sentence.find(char) == -1:
            return False
    return True

У строк есть метод .find() который проверяет находится ли в строке нужный символ, string.find("a") если нужного символа не найдено, то метод возвращает -1 если символ найден то возвращается номер его позиции.

В этой программе мы циклом проходимся по строке, с проверкой есть ли в нем искомый сивол, если символ не найден то получаем -1 и при первом же получении -1 возвращаем False тоетсь символ в строке не найден, если цикл проходит до конца, значит все символы найдены в строке, и тогда мы возвращаем True

  1. Второй способ: Тут суть такова, sentence - это строка с предложением,о сути яволяется списком, использумя метод set мы переводим этот список в множество, и таким образом отсеиваем все повторяющиеся символы, так мы генерируем alphaset который содержит только уникальные символы строки.

    Так мы получаем 2 множества и сравниваем их между собой, если в одном множестве элементов меньше чем в другом, не количество а именно уникальных символов то значит не все символы содержатся в строке.

    from string import ascii_lowercase as alphabet
   
    sentence = "The quick brown fox jumps over the lazy dog"
    alphaset = set(alphabet)

    return alphaset <= set(sentence.lower())

Есть задача: есть число и диапозон из 2 чисел, требуется определить входит ли указанное число в диапозон 2 указанных чисел.

Есть 2 варианта решения, первый это просто сравнение if чтобы число было в промежутке между 2

    if low <= num <= high:
        return True
    return False

Второй способ это создание диапозона из чисел при помощи функции range() Если число входит в диапозон то True будет возвращено автоматически:

    def func21(num, low, high):
        return num in range(low, high)

   def func1():
       """Разделяет список указанным символом
   
       Разделение происходит при помощи метода join обьекта str, который
       принимает список, и разделяет его той строкой у которой вызвается.
       '\n' - перевод строки
       '\t' - табуляция(пробел)
   
       Подобный способ решения удобнее чем простое использование конкатенации
       print(listone[0]+','+listone[1]+','+listone[2]+','+listone[3])
       """
   
       listone = ['первый', 'второй', 'третий', 'четвертый']
       DELIMETER = '\t'
   
       result = DELIMETER.join(listone)
       print(result)