Рубрики
Без рубрики

Советы для начинающих, чтобы сделать алгебру в Python

Есть два типа людей, которые обычно имеют общую сложность при запуске Python: Thos … Теги с Python, учебником, начинающим, математикой.

Есть два рода людей, которые обычно имеют общий Сложность При запуске Python: те, кто узнает его без предыдущего опыта кодирования и тех, кто приходит с низкоуровневого программирования. Я подпадаю под вторую категорию, и когда дело доходит до определенных проблем, я знаю, мы склонны игнорировать возможные собственные решения и пытаться решить их в алгоритмическом способе. Это приятно (и лучше) для обучения, но языки высокого уровня обычно предлагают решения, которые будут легче кодировать, понимать и поддерживать.

Я предполагаю, что вы понимаете списки, словари и множества в Python и основы алгебры.

Содержание

  1. Список, словарь и заданное понимание
  2. Установить операции
    • Наборы наборов
  3. functools модуль

    • functools.reduce.
    • functools.lru_cache.

Список, словарь и заданное понимание

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

mylist = [5,4,3,7,8,1,12]
even = []
for n in mylist:
  if (n%2 == 0):
    even.append(n)
print(even)
# [4,8,12]

Это довольно стандартный для языков С-семейства C-семейства. Тем не менее, самый питон способ использовать Понимание списка :

mylist = [5,4,3,7,8,1,12]
even = [x for x in mylist if x%2 == 0]
print(even)
# [4,8,12]

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

# without filter
[expression for element in sequence]
# with filter
[expression for element in sequence if condition]

Таким образом, другой пример может быть скопировать список строк, изменяя все их в верхний регистр:

names = ['Mikkel', 'Jonas', 'Martha']
uppernames = [name.upper() for name in names]
print(uppernames)
# ['MIKKEL','JONAS','MARTHA']

Теперь вы также можете определить наборы и словари по пониманию:

# sets
set(expression for element in sequence)
{expression for element in sequence}
# dicts (note here's a difference in the key value specification)
dict((key,value) for element in sequence if condition)
{key:value for element in sequence if condition}

Но есть больше! Вам не нужно повторять только одну последовательность. Python позволяет добавлять больше, чем один Для <последовательности> в ваших пониманиях. Давайте посмотрим некоторые примеры:

# dictionary merge
merged = {k:v for (k,v) in dict1 for (k,v) in dict2}
# cartesian product of two sets
# - note that the result is not a dict, but a set of tuples
cartesian = {(x,y) for x in set1 for y in set2}

Здесь Вы найдете больше примеров в списке, Dict и установленных возможностях.

Установить операции

Теперь с заданным пониманием легко определить обычные операции между наборами. Тем не менее, Python уже определяет эти операции в результате чего:

abcde = {'a','b','c','d','e'}
vowels = {'a','e','i','o','u'}

intersection = abcde & vowels
# {'a','e'}
union = abcde | vowels
# {'a', 'b', 'c', 'd', 'e', 'i', 'o', 'u'}
difference = abcde - vowels
# {'b','c','d'}
symmetricDifference = abcde ^ vowels
# {'b','c','d','i','o','u'}

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

Теперь существуют не только операции, которые приводят к новым комплектам, но и логическими операторами, такие как:

isStrictSubset1 = abcde < abcde
# False
isStrictSubset2 = difference < abcde
# True

isSubset1 = abcde <= vowels
# False
isSubset2 = abcde <= abcde
# True
isSubset3 = difference <= abcde
# True

isEmptySet = bool(abcde)
# False
isEmptySet = bool(abcde - abcde)
# True

Наборы наборов

Ограничение иметь в виду при работе с наборами в Python в том, что наборы могут содержать только одновременные типы (INT, CHAR, TVES …) и сами настраиваются несомненно. По этой причине, если вы хотите хранить набор наборов, вы должны использовать вместо списка наборов. К счастью, на этот раз список пополнений в списке «Список» могут сделать его для замены заданных операций.

set1 = [{1,2,3}, {'a','b','c'}, {'A','B','C'}]
set2 = [{'a','b','c'}, {'b','c'}, {'c'}]

intersection = [x for x in set1 if x in set2]
# [{'a','b','c'}]
difference  = [x for x in set1 if x not in set2]
# [{1,2,3}, {'a','b','c'}, {'A','B','C'}]
union = set2 + difference
# [{'a', 'b', 'c'}, {'b', 'c'}, {'c'}, {1, 2, 3}, {'A', 'B', 'C'}]

# You get the idea

Модуль Functools.

Это полезный модуль Python, который обеспечивает очень интересные утилиты, из которых я расскажу только о двух: Уменьшить и @lru_cache Отказ

Здесь Вы найдете полную официальную документацию по этому модулю.

functools.reduce.

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

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

set1 = [{1,2,3}, {'a','b','c'}, {'A','B','C'}]
union = set() 
for x in set1:
  union = union | x

Но с уменьшением точного же поведения получается как следует:

set1 = [{1,2,3}, {'a','b','c'}, {'A','B','C'}]
union = functools.reduce(set.union, set1)
# {1, 2, 3, 'a', 'A', 'b', 'c', 'B', 'C'}

Первый аргумент – это функция для применения, а вторая – это список, к которому он будет применен, в накопленном виде. Обратите внимание, что я не использовал оператора |. как прежде. Вместо этого мне пришлось использовать названную функцию Set.union Отказ Чтобы найти именованные функции, соответствующие набору операторов, вы можете ввести Помощь (набор) в вашей консоли Python.

@ functools.lru_cache.

Как вы можете себе представить, хотя состоится легко напечатать и понимать, они не именно дешевы в вычислении. Модуль functools Предоставляет нам несколько способов кэшировать результаты функции (обратите внимание, что аналогичное поведение получается для методов класса с @ functools.cached_property ).

@functools.lru_cache
def count_vowels(sentence):
  sentence = sentence.casefold()
  return sum(sentence.count(vowel) for vowel in 'aeiou')

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

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

@functools.lru_cache
def factorial(n):
  return n*factorial(n-1) if n else 1

Практический пример

Посмотрим, как это применяется, например, для отслеживания знакомых отношений.

import functools

# https://en.wikipedia.org/wiki/Transitive_closure
def transitiveClosure(relation):
    closure = relation
    while True:
        delta = {(x,y) for (x,r1) in closure for (r2,y) in closure if r1 == r2}
        newClosure = closure | delta
        if newClosure == closure:
            break
        closure = newClosure
    return closure;

# Direct descendance information
childRelation = {
         ('Martha','Ulrich'),
         ('Mikkel','Ulrich'),
         ('Magnus','Ulrich'),
         ('Mads','Tronte'),
         ('Ulrich','Tronte'),
         ('Tronte','Agnes'),
         ('Jonas','Hannah'),
         ('Jonas','Michael')}

descendantRelation = transitiveClosure(childRelation)

# Some functions using our new relation
@functools.lru_cache
def ancestorsOf(x):
    return {b for (a,b) in descendantRelation if a==x}

def isDescendantOf(x,y):
    return y in ancestorsOf(x)

def areRelated(peopleList):
    ancestors = [ancestorsOf(x) for x in peopleList]
    commonAncestors = functools.reduce(set.intersection, ancestors)
    return bool(commonAncestors)

print(ancestorsOf('Martha'))
# {'Agnes','Tronte','Ulrich'}
print(isDescendantOf('Jonas', 'Agnes'));
# False
print(isDescendantOf('Martha', 'Agnes'));
# True
print(areRelated(['Martha', 'Jonas']));
# False
print(areRelated(['Martha', 'Magnus', 'Mikkel']));
# True

Я надеюсь вы найдете эту информацию полезной. У вас есть какие-либо советы, которые вы хотите поделиться? Если у вас есть опыт решения ваших математических заданий с Python (или любым другим языком) Я хотел бы прочитать их!

Оригинал: “https://dev.to/miguelmj/beginner-tips-to-do-algebra-in-python-477e”