Выполните операцию над списком Python без использования глобальных переменных. - PullRequest
0 голосов
/ 05 января 2019

У меня есть список Python (например, lst = [2, 3, 5]). В соответствии с каждым элементом lst, я хочу построить пустую матрицу следующим образом: это должен быть квадратный массив того же размера, что и рассматриваемый элемент lst, и должен быть заполнен квадратом этого значения элемент.

Вот как я сейчас подхожу к проблеме:

import numpy as np
lst = [2,3,5]
for i in range(len(lst)):
    globals()['mat'+str(lst[i])] = np.full( (lst[i],lst[i]), lst[i]**2 )

print globals()['mat'+str(2)]
print " "
print globals()['mat'+str(3)]
print " "
print globals()['mat'+str(5)]    

[[4 4]
 [4 4]]

[[9 9 9]
 [9 9 9]
 [9 9 9]]

[[25 25 25 25 25]
 [25 25 25 25 25]
 [25 25 25 25 25]
 [25 25 25 25 25]
 [25 25 25 25 25]]

Какой эффективный способ выполнить эту задачу без использования глобальных переменных?

1 Ответ

0 голосов
/ 05 января 2019

Здесь нет проблемы эффективности, независимо от того, как вы называете или генерируете массивы. Независимо от наименования, вы должны использовать np.full для каждого массива. Создав массив, вы можете собрать его в виде списка, словаря или присвоить переменной.

Я бы собрал массивы в список:

In [212]: lst = [2,3,5]
In [213]: lst1 = [np.full((i,i),i**2) for i in lst]
In [214]: lst1
Out[214]: 
[array([[4, 4],
        [4, 4]]), array([[9, 9, 9],
        [9, 9, 9],
        [9, 9, 9]]), array([[25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25]])]

Если вам необходимо присвоить имена, используйте что-то вроде:

In [215]: mat2, mat3, mat5 = lst1
In [216]: mat3
Out[216]: 
array([[9, 9, 9],
       [9, 9, 9],
       [9, 9, 9]])

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

Говоря о словарях, мы можем преобразовать список в один с помощью:

In [217]: adict = {f'mat{i}': x for i,x in zip(lst, lst1)}
In [218]: adict
Out[218]: 
{'mat2': array([[4, 4],
        [4, 4]]), 'mat3': array([[9, 9, 9],
        [9, 9, 9],
        [9, 9, 9]]), 'mat5': array([[25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25],
        [25, 25, 25, 25, 25]])}

(Здесь я использую новый f-literal строковый синтаксис.)

...