ProgrammingFA
783 subscribers
5 photos
3 files
19 links
Все про программирование. Статьи, видео, обсуждения.

Бот - @ProgrammingFAbot
Чат - @ProgrammingFAchat
По вопросам и рекламе - @abinba
Download Telegram
#Python

Differences Between bytes, str, and
unicode

In Python 3, there are two types that represent sequences of characters: bytes and str.
bytes contain raw 8-bit values (binary data)
str contain Unicode characters

In Python 2, there are str and unicode.
str contain raw 8-bit values (binary data)
unicode contain Unicode characters

Use of functions:
Unicode -> binary data = encode(‘utf-8’)
binary data -> Unicode = decode(‘utf-8’)

Or you can use different encoding, but utf-8 is most commonly used.

Python 2:
1) unicode and str instances seem to be the same type
when a str only contains 7-bit ASCII characters
2) file operations default to binary encoding

Python3:
1) bytes and str instances are never equivalent—
not even the empty string—so you must be more deliberate about the types of character
2) operations involving file handles (returned by the
open built-in function) default to UTF-8 encoding

So, If you want to read or write binary data to/from a file, always open the file using a binary mode (like 'rb' or 'wb')
#Python

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

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

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

value = [len(x) for x in open(‘/tmp/my_file.txt’)]
print(value)

>>>
[100, 57, 15, 1, 12, 75, 5, 86, 89, 11]

Чтобы решить эту проблему, мы можем использовать выражения-генераторы, которые не считают все значения при запуске. Вместо этого, они вычисляют разовые значения из листа.

it = (len(x) for x in open(‘/tmp/my_file.txt’))
print(it)


>>>
<generator object <genexpr> at 0x101b81480>

Данный итератор двигается на шаг при одном проходе, вычисляя следующее значение.

print(next(it))
print(next(it))

>>>
100
57


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

Замыкания и области видимости переменных

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

Примерно так выглядит реализация этой задачи:

def sort_priority(values, group):
def helper(x):
if x in group:
return (0, x)
return (1, x)
values.sort(key=helper)

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)

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

Это работает так по следующим причинам:

- Python поддерживает замыкание - функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся ее параметрами. Поэтому функция helper имеет доступ к переменной group, являющаяся параметром функции sort_priority.

- В Python есть специфичный метод сравнивание кортежей, сначала сравниваются значения в нулевом индексе, затем в первом, затем во втором и так далее. Поэтому возвращаемое значение с функции helper позволяет сортировать две различные группы.


Теперь мы хотим убедиться, находится ли группа с приоритетом в общем списке. Как это сделать? Посмотрите на следующий код.

def sort_priority2(numbers, group):
found = False
def helper(x):
if x in group:
found = True
return (0, x)
return (1, x)
numbers.sort(key=helper)
return found

found = sort_priority2(numbers, group)
print(‘Found:’, found)
print(numbers)

>>>
Found: False
[2, 3, 5, 7, 1, 4, 6, 8]

Отсортировано правильно, но он не нашел ту группу, элементы которых определенно есть в общей. Из-за чего?

Именно. Из-за области видимости переменных. При объявлении функции helper, мы не изменяем переменную found, мы инициализируем новую для этой области переменную found и приравниваем к True. Поэтому выводится значение именно из области функции sort_priority2.

Как можно решить эту проблему? В Python 3 есть специальный синтаксис для взятия данных из замыканий - выражение nonlocal.

def sort_priority3(numbers, group):
found = False
def helper(x):
nonlocal found
if x in group:
found = True
return (0, x)
return (1, x)
numbers.sort(key=helper)
return found

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

class Sorter(object):
def __init__(self, group):
self.group = group
self.found = False

def __call__(self, x):
if x in self.group:
self.found = True
return (0, x)
return (1, x)


sorter = Sorter(group)
numbers.sort(key=sorter)
assert sorter.found is True
#Python

yield

Если вы когда-нибудь встречали слово yield в python коде и были озадачены, что же это такое, то вы сможете найти ответ на свой вопрос в данной статье

https://habr.com/ru/post/132554/