<jupyter_start><jupyter_text>Python 3 словари, множества, модуль collections бонусная часть: импорт модулейMIPT 2020<NAME>  Словари  хранят пары ключ => значение<jupyter_code>a = {1: 2, "key": "value"}

print(a)
print(1 in a)
print(2 in a)<jupyter_output>{1: 2, 'key': 'value'}
True
False<jupyter_text>ключи True и False ведут себя как ключи 1 и 0<jupyter_code>a = {0: 0, 1: 1}

print(a[True])
print(a[False])
print(a)

a[True] = 2
print(a)
{0:0, True: True, False: False}<jupyter_output><empty_output><jupyter_text>None - вполне валидный ключ<jupyter_code>a = {0: 0}
a[None] = None
a<jupyter_output><empty_output><jupyter_text>удаление элементов<jupyter_code>a = {0: 0, "key": "value"}
a

del a[0]
a

a.clear()
a<jupyter_output><empty_output><jupyter_text>наличие ключа<jupyter_code>0 in {0: 1}
1 in {0: 1}
a = {1: 1}
a.get('key', 'default value')
a.get(1, 'default value')<jupyter_output><empty_output><jupyter_text>итерирование по ключам, значениям, парам<jupyter_code>a = {0: 1, "key": "value"}
print(f"a.keys() = {list(a.keys())}")
print(f"a.values() = {list(a.values())}")
print(f"a.items() = {list(a.items())}")<jupyter_output>a.keys() = [0, 'key']
a.values() = [1, 'value']
a.items() = [(0, 1), ('key', 'value')]<jupyter_text>добавление нескольких элементов<jupyter_code>a = {0: 1, 2: 3}
b = {"key": "value", 2: 9000}
a.update(b)
print(a)
print(b)<jupyter_output>{0: 1, 2: 9000, 'key': 'value'}
{'key': 'value', 2: 9000}<jupyter_text>Множества Похоже на словарь, который хранит только ключи.<jupyter_code>a = {1, 2}
a.update({True, False, 3})
a
0 in {0}
False in {0}
False in {4, 5}
a = {1, 2}
a.update({3, 4})
a.add(5)
a
a = {1, 2}
a.remove(1)
a<jupyter_output><empty_output><jupyter_text>операции над множествами<jupyter_code>a = {1, 2}
b = {1, "key"}

b - a
a - b
a & b
a | b
a ^ b<jupyter_output><empty_output><jupyter_text>то же самое<jupyter_code>a = {1, 2}
b = {1, "key"}

b.difference(a)
a.difference(b)
a.intersection(b)
a.union(b)
a.symmetric_difference(b)
a = {1, 2}
a.issubset(a)
a.issubset(a)
a.isdisjoint({})<jupyter_output><empty_output><jupyter_text>Изменение существующей коллекции<jupyter_code>a = {1, 2}
a &= {2, 3}
a
a = {1, 2}
a.intersection_update({2, 3})
a
{"key": "value"}.__class__ 
{"key"}.__class__

{}.__class__ 
set()
dict()<jupyter_output><empty_output><jupyter_text>Hashable types хеш ключей не должен изменяться<jupyter_code>{(1, 2): 3}
{[1, 2]: 3}<jupyter_output><empty_output><jupyter_text>встроенная функция **hash**<jupyter_code>hash(0)
hash(42)
hash(1.2)
hash("str")
hash(True)
hash((1, 2))<jupyter_output><empty_output><jupyter_text>unhashable types<jupyter_code>hash([1, 2])
hash((1, [2, 3]))
hash({1, 2})
hash({1: 2})<jupyter_output><empty_output><jupyter_text>Неизменяемые коллекции* list - tuple* set - frozenset* dict - ???<jupyter_code>hash(tuple([1, 2]))

hash(frozenset({1, 2}))

hash(frozenset({1: 2, 3: 4}.items()))
a = {1: 2, "key": "value"}
a 

frozenset(a)
frozenset(a.items())

dict(frozenset(a.items()))<jupyter_output><empty_output><jupyter_text>Python 3.6+ и порядок вставки ключей<jupyter_code>print({1, 2})
print({2, 1})

print({1: 1, 2: 2})
print({2: 2, 1: 1})
a = {0: 'v0'}
a[1] = 'v1'
a[2] = 'v2'
print(a)

del a[1]
print(a)

a[1] = 'v1.1'
print(a)

a[2] = 'v2.1'
print(a)<jupyter_output>{0: 'v0', 1: 'v1', 2: 'v2'}
{0: 'v0', 2: 'v2'}
{0: 'v0', 2: 'v2', 1: 'v1.1'}
{0: 'v0', 2: 'v2.1', 1: 'v1.1'}<jupyter_text>Collectionshttps://docs.python.org/3/library/collections.html  OrderedDicthttps://docs.python.org/3/library/collections.htmlcollections.OrderedDict<jupyter_code>from collections import OrderedDict

d = OrderedDict({1: 1})
d["key"] = value
d

d.move_to_end(1)
d

d.popitem(1)
d<jupyter_output><empty_output><jupyter_text>defaultdicthttps://docs.python.org/3/library/collections.htmlcollections.defaultdict<jupyter_code>from collections import defaultdict

d = defaultdict(list)

d[0] += [1, 2]

d
from collections import defaultdict
d = defaultdict(lambda: 42)

d[0]
d

d[1] = 1
d<jupyter_output><empty_output><jupyter_text>dequehttps://docs.python.org/3/library/collections.htmlcollections.deque<jupyter_code>from collections import deque

d = deque([1, 2])
d.append(3)
d.appendleft(4)
d

d.pop()
d.popleft()
d<jupyter_output><empty_output><jupyter_text>counterhttps://docs.python.org/3/library/collections.htmlcollections.Counter<jupyter_code>from collections import Counter

c = Counter()
c.update([1, "two", "two", "three"])
c
c.items()

c["three"] = 3
c
Counter([1, 2, 2])
Counter({1, 2, 2})
Counter({1: 1, 2: 2})
Counter(one=1, two=2)<jupyter_output><empty_output><jupyter_text>namedtuplehttps://docs.python.org/3/library/collections.htmlcollections.namedtuple<jupyter_code>from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

print(Point(1, 2))
x, y = Point(1, 2)
(x, y)

for value in Point(1, 2):
    print(value)

print(Point(42, 42).x)
from typing import NamedTuple

Point = NamedTuple('Point', [('x', str), ('y', str)])
Point(1, 2)
class Point(NamedTuple):
    "very important comment"
    x: int = 0
    y: int = 0
        
Point(y=3)
Point.__doc__<jupyter_output><empty_output><jupyter_text>Import<jupyter_code>import numpy
import numpy as np
import scipy.linalg as sla

from typing import NamedTuple
from typing import NamedTuple as OldNamedTuple

# bad practice!
# from typing import * 

# import local file from same directory
# from .localfilename import function_name<jupyter_output><empty_output><jupyter_text>import works only once<jupyter_code>from time import time

for i in range(3):
    t1 = time()
    import tensorflow as tf 
    t2 = time()
    print(f"dt = {t2-t1}")

import pprint

print = pprint.pprint

print(pprint)
print(dir(pprint))
print(pprint.__dict__)<jupyter_output>{'PrettyPrinter': <class 'pprint.PrettyPrinter'>,
 '_StringIO': <class '_io.StringIO'>,
 '__all__': ['pprint',
             'pformat',
             'isreadable',
             'isrecursive',
             'saferepr',
             'PrettyPrinter'],
 '__builtins__': {'ArithmeticError': <class 'ArithmeticError'>,
                  'AssertionError': <class 'AssertionError'>,
                  'AttributeError': <class 'AttributeError'>,
                  'BaseException': <class 'BaseException'>,
                  'BlockingIOError': <class 'BlockingIOError'>,
                  'BrokenPipeError': <class 'BrokenPipeError'>,
                  'BufferError': <class 'BufferError'>,
                  'BytesWarning': <class 'BytesWarning'>,
                  'ChildProcessError': <class 'ChildProcessError'>,
                  'ConnectionAbortedError': <class 'ConnectionAbortedError'>,
                  'ConnectionError': <class 'ConnectionError'>,
                  'ConnectionRefusedError': <class 'Co[...]<jupyter_text>Avoid cyclic import!<jupyter_code>## file first.py

def first_func():
    from .second import second_func
    ...

## file second.py

def second_func():
    from .first import first_func
    ...
import sys

sys.path

# sys.path.append(another_path)<jupyter_output><empty_output><jupyter_text>\_\_name\_\_https://stackoverflow.com/questions/419163/what-does-if-name-main-do<jupyter_code>print(__name__)

import pprint
print(pprint.__name__)<jupyter_output>'__main__'
'pprint'
{'fraction_non_alphanumeric': 0.1755799416585637, 'fraction_numerical': 0.03319905542436449, 'mean_word_length': 5.065711878685763, 'pattern_counts': {'":': 6, '<': 110, '<?xml version=': 0, '>': 110, 'https://': 7, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '25', 'dir': 'jupyter-structured-clean-dedup', 'id': '250903', 'license': 'MIT', 'n_tokens_mistral': 3156, 'n_tokens_neox': 3036, 'n_words': 592, 'path': 'Seminar3.ipynb', 'repo_name': 'Kright/PythonCourse2020', 'size': '7208'}