Моя обреченная попытка описать все Python, необходимые для начала карьеры в науке о данных

Мотивация

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

Очевидно, что одна серия не может охватить все темы, необходимые для успешной карьеры… но, перефразируя Икара, «здесь ничего не выйдет».

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

Наиболее распространенные «примитивные» типы Python

Примитивы - самые основные типы. Их можно комбинировать и связывать более интересными способами как непримитивы (следующий раздел!).

- Целые числа, числа с плавающей запятой, сложные

Существует три основных числовых типа: целые числа, числа с плавающей запятой и комплексные. Целые числа — это целые числа без дробной части. Плавающие числа — это числа с плавающей запятой, которые могут включать дробную часть.

>>> type(4)
<class 'int'>
>>> type(4.2)
<class 'float'>

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

>>> 1.2e-3
0.0012
>>> 1.2e3
1200.0

Комплексные числа включают действительную и мнимую (j) составляющие.

>>> type(4+2j)
<class 'complex'>
>>> (4+2j).real
4.0
>>> (4+2j).imag
2.0

Если вы не знакомы с комплексными числами, ознакомьтесь с некоторыми из моих статей об их значении в математике и естественных науках.

- Булевы значения

Верно и Неверно! Обратите внимание на заглавные буквы. Здесь нет ничего сложного, но в Python все становится немного сложнее, когда небулевые значения преобразуются в логические.

>>> bool(None)
False
>>> bool("")
False
>>> bool([])
False
>>> bool("Any non-empty string")
True
>>> bool(["Any non-empty list, dict, etc."])
True

Мы называем эти ценности «истинными». None является истинным значением False, "" – истинным значением False, а "Любая непустая строка" – истинным значением True.

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

- Струны

Строки Python могут быть заключены в одинарные или двойные кавычки. Их можно объединить вместе с помощью + или неявно, разделив их пробелами.

>>> "Implicitly" ' concatenated ' "strings"
'Implicitly concatenated strings'

Значения могут быть заменены на f-строки, которые имеют умные названия… это строки с буквой f впереди (новый стиль).

>>> def scream_greeting(name: str):
...     print(f"HI, MY NAME IS {name.upper()}")
...
>>> name="Peter Bryan"
>>> scream_greeting(name=name)
HI, MY NAME IS PETER BRYAN

Вы можете делать действительно причудливые вещи с f-strings.

  • Имя и значение переменной (удобно для отладки!)
>>> variable = 45
>>> print(f"{variable = }")
variable = 45
  • Десятичный до nцифр
>>> approx_pi = 22/7
>>> print(f"Pi to 2 places {approx_pi:.2f}")
Pi to 2 places 3.14
>>> print(f"Pi to 3 places {approx_pi:.3f}")
Pi to 3 places 3.143
>>> print(f"Pi to 4 places {approx_pi:.4f}")
Pi to 4 places 3.1429
  • Проценты
>>> percentage = 0.85
>>> print(f"{percentage = :.1%}")
percentage = 85.0%
  • Причудливое форматирование запятой
>>> big_number = 100000000000000000
>>> print(f"The big number's value is {big_number:,}")
The big number's value is 100,000,000,000,000,000
  • Удобное форматирование даты
>>> import datetime
>>> current_utc_time = datetime.datetime.utcnow()

>>> print(f"Standard ugly format: {current_utc_time}")
Standard ugly format: 2022-12-31 02:28:36.406682

>>> print(f"Pretty format: {current_utc_time:%m/%d %H:%M:%S%p}")
Standard ugly format: 12/31 02:28:36AM

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

>>> import logging
>>> name="Peter Bryan"
>>> logging.error("Uh, oh. It's %s.", name)
ERROR:root:Uh, oh. It's Peter Bryan.

Многострочные строки удобны для docstrings и других строк, которые, ну… многострочные. Использование тройных кавычек.

>>> print("""
... A
... multi-line
... string""")

A
multi-line
string

Наиболее распространенные «непримитивные» типы Python

Непримитивы объединяют и связывают типы примитивов в полезные структуры данных. Давайте совершим краткий обзор общих коллекций.

- Набор

Наборы неупорядочены…

>>> {1, 2, 3} == {3, 2, 1}
True

…и содержат строго уникальные значения…

>>> {1, 2, 3, 3, 3, 3}
{1, 2, 3}

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

- Список

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

>>> sample_list = [1, 2, 3, 4]

# You can add new iptems
>>> sample_list.append(5)
>>> print(sample_list)
[1, 2, 3, 4, 5]

# You can remove items by value...
>>> sample_list.remove(4)
>>> print(sample_list)
[1, 2, 3, 5]

# or by position
>>> sample_list.pop(0)
1
>>> print(sample_list)
[2, 3, 5]

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

- Кортеж

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

>>> sample_tuple = (1, 2, 3)

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

Как показано, кортеж определяется значениями, разделенными запятыми в скобках.

- Словарь

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

>>> sample_dict = {"key1": "value1", "key2": "value2"}
>>> print(sample_dict)
{'key1': 'value1', 'key2': 'value2'}

# The length of a dict is the number of key-value pairs
>>> print(len(sample_dict))
2

# You can iterate over keys, values, or both
>>> print(list(sample_dict.keys()))
['key1', 'key2']
>>> print(list(sample_dict.values()))
['value1', 'value2']
>>> print(list(sample_dict.items()))
[('key1', 'value1'), ('key2', 'value2')]

# Unlike tuples, dictionaries are mutable
>>> sample_dict["key3"] = "value3"
>>> sample_dict.pop("key1")
'value1'
>>> print(sample_dict)
{'key2': 'value2', 'key3': 'value3'}

Как показано, пары ключ-значение обозначаются двоеточием. Список пар разделен запятыми.

- Вложенные структуры

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

Вы можете составить список из списков…

>>> [[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6]]

Или словарь с ключами кортежа…

>>> {(1, 2): "One and two", (3, 4): "Three and four"}
{(1, 2): 'One and two', (3, 4): 'Three and four'}p

Вы поняли! Обещаю, однако, все становится сложнее. Попробуем составить словари с разными типами ключей.

>>> {(1, 2): "Tuples are fine as keys in dictionaries"}
{(1, 2): 'Tuples are fine as keys in dictionaries'}

>>> {{1, 2}: "But sets..."}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

>>> {[1, 2]: "And lists..."}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

>>> {{1: 2}: "And dictionaries are not!"}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Сейчас мы объясним это упрощающей ложью: словари могут использовать только неизменяемые типы в качестве ключей. Менее просто, но более правдиво, потому что в качестве ключей можно использовать только «хешируемые» объекты. Потребуется немного больше чтения, чтобы полностью понять, что это значит. Мы доберемся туда!

Что дальше?

Мы рассмотрим основные операторы Python. Спасибо за прочтение! Если вы заинтересованы в продолжении чтения, обязательно подпишитесь!