首页 > 解决方案 > 在循环python中迭代,分配var中的所有元素

问题描述

我写了一个函数,它需要一个密码并加密它。密码:“verylongpassword2021” 这个想法是创建一个方阵,如果缺少字母,将添加“x”。

密码显示为:

[['v' 'e' 'r' 'y' 'l']
 ['o' 'n' 'g' 'p' 'a']
 ['s' 's' 'w' 'o' 'r']
 ['d' '2' '0' '2' '1']
 ['x' 'x' 'x' 'x' 'x']]

从上到下按列读取的加密密码。加密后的密码将显示为:

"vosdxens2xrgw0xypo2xlar1x".

我很难将它分配给一个 var。当我打印我收到的 var[array('v', dtype='<U1'), array('o', dtype='<U1'), array('s', dtype='<U1'), array('d', dtype='<U1'), array('x', dtype='<U1'), array('e', dtype='<U1'), array('n', dtype='<U1'), array('s', dtype='<U1'), array('2', dtype='<U1'), array('x', dtype='<U1'), array('r', dtype='<U1'), array('g', dtype='<U1'), array('w', dtype='<U1'), array('0', dtype='<U1'), array('x', dtype='<U1'), array('y', dtype='<U1'), array('p', dtype='<U1'), array('o', dtype='<U1'), array('2', dtype='<U1'), array('x', dtype='<U1'), array('l', dtype='<U1'), array('a', dtype='<U1'), array('r', dtype='<U1'), array('1', dtype='<U1'), array('x', dtype='<U1')]

你知道我在这里做错了什么吗?我在encrypted_matrix_password = []打印时遇到了问题。

import numpy as np
import math

def encrypt_matrix(password):
    len_password = len(password)
    n_matrix = math.ceil(pow(len_password, 0.5))

    # turn password into a list, by splitting each letter
    tokens = list(password)

    # add "X" to tokens until == 4 x4
    while len(tokens) < n_matrix ** 2:
        tokens.append("x")
    tokens_np_array = np.array(tokens)

    # create matrix n_matrix **2, write each character in matrix, starting from up row left, to right
    tokens_n_matrix = np.reshape(tokens_np_array, (n_matrix, n_matrix))
    print(tokens_n_matrix)

    # read matrix by columns starting up down
    read_matrix = tokens_n_matrix.copy(order="F")

    encrypted_matrix_password = []
    for char in np.nditer(read_matrix):
        print(char, end="")
        encrypted_matrix_password.append(char)

    # return encrypted_matrix_password
    print(encrypted_matrix_password)

    enc_mat = encrypt_matrix("verylongpassword2021")

标签: pythonarraysnumpyencryption

解决方案


我已经缩短了你的代码。我用一个表达式填充了字符串,而不是循环。我按列“读出”矩阵(顺序'F'),并join直接创建了一个字符串。无需显式迭代。ravel执行copy('F')并将其转换为 1d 。

def encrypt_matrix(password):
    len_password = len(password)
    n_matrix = np.ceil(pow(len_password, 0.5)).astype(int)
    # pad string
    password += "x"*(n_matrix**2-len(password))
    # turn password into a list, by splitting each letter
    tokens = list(password)

    tokens_n_matrix = np.reshape(tokens, (n_matrix, n_matrix))
    print(tokens_n_matrix)
    encrypted_password=''.join(tokens_n_matrix.ravel(order='F'))
    return encrypted_password
    
In [11]: encrypt_matrix("verylongpassword2021")
[['v' 'e' 'r' 'y' 'l']
 ['o' 'n' 'g' 'p' 'a']
 ['s' 's' 'w' 'o' 'r']
 ['d' '2' '0' '2' '1']
 ['x' 'x' 'x' 'x' 'x']]
Out[11]: 'vosdxens2xrgw0xypo2xlar1x'

这可能有助于可视化操作:

In [14]: x = np.arange(12).reshape(3,4)
In [15]: x
Out[15]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [16]: x.ravel()
Out[16]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [17]: x.ravel(order='F')
Out[17]: array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])
In [25]: np.arange(12).reshape(4,3, order='F').ravel(order='C')
Out[25]: array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])

推荐阅读