С применением функции
range()
генерируется список смещений и производится индексация с одинаковыми номерами строк и столбцов, выбирающая М[0][0], затем М[1][1]
и т.д. Во второй строке индекс столбца уравновешивается для извлечения М[0][2]
, М[1][1]
и т.д. (мы предполагаем, что матрица имеет равное количество строк и столбцов):M = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# Диагональ
[M[i][i] for i in range(len(M))] # [1, 5, 9]
# Обратная диагональ
[M[i][len(M)-1-i] for i in range(len(M))] # [3, 5, 7]
В данном случае однократное списковое включение «сплющивает» матрицу до вектора, т.е. списка чисел. Чтобы понять такой код, его можно преобразовать к виду простых операторов:
Чтобы сохранить матрицу, достаточно использовать двойное списковое включение:
res = []
for row in М: # Эквиваленты в виде операторов
for col in row: # Отступ для частей, находящихся дальше справа
res.append(col + 10)
Чтобы сохранить матрицу, достаточно использовать двойное списковое включение:
[[col + 10 for col in row] for row in M]
Что выведет код?
Anonymous Quiz
59%
[2, 4, 6, 12, 15, 18, 28, 32, 36]
26%
[[2, 4, 6], [12, 15, 18], [28, 32, 36]]
11%
[2, 6, 12, 8, 15, 24, 14, 24, 36]
5%
Error
Мы можем использовать списковые включения для комбинирования значений множества матриц. В задаче выше строится плоский список, который содержит результат попарного перемножения матриц.
Списковое включение может применяться также как разновидность операции проецирования столбцов. Стандартный API-интерфейс для работы с базами данных SQL в Python возвращает результаты запросов в форме последовательности последовательностей вроде следующей ниже; список представляет таблицу, кортежи — строки, а элементы в кортежах — значения столбцов:
С использованием цикла
«столбца» вручную, но списковые включения способны выполнить такую работу за один шаг, к тому же быстрее:
listoftuples = [('bob', 35, 'mgr'), ('sue', 40, 'dev'), ('jack', 51, 'cio')]
С использованием цикла
for
можно было бы извлечь все значения из выбранного«столбца» вручную, но списковые включения способны выполнить такую работу за один шаг, к тому же быстрее:
[age for (name, age, job) in listoftuples] # 35, 40, 52
Как по умолчанию сортирует pandas.sort_values()?
Anonymous Quiz
14%
По убыванию
65%
По возрастанию
9%
Pandas решает сам на основании характера данных
12%
Без явного указания типа сортировки не запустится
DataFrame.sort_values(by, *, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)
Булевый параметр
ascending
отвечает за тип сортировки и по умолчанию равен True, т.е. датафрейм сортируется по умолчанию от меньшего к большему.Чем отличается генераторная функция с yield от классической?
Anonymous Quiz
29%
Возвращает управление вызывающему коду на каждой итерации
14%
При ее возобновлении восстанавливается предыдущее состояние i и N
56%
Все вышеперечисленное
Генератор — это специальная функция, которая возвращает итератор, с помощью которого можно обойти некоторую последовательность значений.
В крупных программах генераторы могут быть лучше в плане памяти и производительности. Они позволяют функциям избежать выполнения всей работы заранее, что особенно полезно, когда результирующие списки большие или получение каждого значения требует длительных вычислений. Генераторы распределяют время, необходимое для производства серии значений, по всем итерациям цикла.
К протоколу генераторных функций добавлен метод next. Он осуществляет переход на следующий элемент в серии результатов, а также снабжает вызывающий код возможностью взаимодействия с генератором для влияния на его работу.
Формально yield теперь имеет форму не оператора, а выражения, которое возвращает
элемент, переданный next.
В крупных программах генераторы могут быть лучше в плане памяти и производительности. Они позволяют функциям избежать выполнения всей работы заранее, что особенно полезно, когда результирующие списки большие или получение каждого значения требует длительных вычислений. Генераторы распределяют время, необходимое для производства серии значений, по всем итерациям цикла.
def gen():
for i in range(10):
X = yield i
print(X)
G = gen()
print(next(G)) # Сначала должен вызываться next(), чтобы запустить генератор
К протоколу генераторных функций добавлен метод next. Он осуществляет переход на следующий элемент в серии результатов, а также снабжает вызывающий код возможностью взаимодействия с генератором для влияния на его работу.
Формально yield теперь имеет форму не оператора, а выражения, которое возвращает
элемент, переданный next.
Эта задача — логическое продолжение предыдущей. Мы имеем дело с генераторной функцией.
Значения отправляются генератору G путем вызова
Значения отправляются генератору G путем вызова
G.send(значение)
. Затем код генератора возобновляет выполнение, и выражение yield
в генераторе возвращает значение, переданное send
. Если вызывается обычный метод G.__next_() (или его эквивалент next(G))
для продвижения вперед, тогда yield
просто возвращает None
.
>>> next(G) # Сначала должен вызываться next(), чтобы запустить генератор
... 0
>>> G.send(77)
... 77
... 1