[英]two dimensional array for encryption in python
我想让用户制作任何必要大小的表。 首先,他将输入行数和列数,然后为每一列和每一行输入一对数字,然后输入其余单元格中的数据。 这是一个例子:
row\column| 23 | 54 | 34 | 75
-------------------------------------
65 | AM | h | 9 | C
-------------------------------------
78 | 56 | in | 13 | ok
因此,基本上,在输入所有信息之后,他应该能够说7834并得到13,反之亦然(例如,输入9C并得到65346575)。
我尝试了一下,但我理解为什么它不起作用,但这是我唯一的想法。
nc = int(raw_input('Input number of columns: '))
nr = int(raw_input('Input number of rows: '))
table = [[raw_input('Input two digits for each column: ') for i in range(2, nc)] for i in range(1)]
table = [[raw_input('Input two digits for each row: ') for i in range(1)] for i in range(2, nr)]
table = [[raw_input('Input data: ') for i in range(2, nc)] for i in range(2, nr)]
任何帮助表示赞赏。
不会那样工作。
实际上,我有点说谎。 那种方式会起作用(我对您编写的生成器有麻烦):
>>> table = [[raw_input('Input data: ') for i in range(1, nc+1)] for i in range(1, nr+1)]
Input data: 1
Input data: 2
Input data: 3
Input data: 4
Input data: 5
Input data: 6
Input data: 7
Input data: 8
Input data: 9
>>> table
[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
但这就是您一开始所要求的-您似乎希望最终用户能够输入列标题和行标题,然后填充数据。
要是我们:
table = [[raw_input('Input data: {},{} '.format(a,b)) for a in range(0, nc)] for b in range(0, nr)]
那么我们可以得到:
Input data: 0,0 None
Input data: 1,0 1
Input data: 2,0 2
Input data: 0,1 a
Input data: 1,1 Ted
Input data: 2,1 Fred
Input data: 0,2 b
Input data: 1,2 3.214
Input data: 2,2 Copy
>>> table
[['None', '1', '2'], ['a', 'Ted', 'Fred'], ['b', '3.214', 'Copy']]
现在,该方案的混乱之处在于,要在“网格”中找到坐标,您必须读取每个列标题并获取其位置,然后读取每个行标题以获取其位置。 那么你也能 :
值=网格[r] [c]
现在,进行反向操作变得更加困难-您必须阅读每个单元格,才能获取行标题和列标题。
哦,我们还没有进行任何错误检查,以确保您不会输入相同的两行或标题,这将完全打击您的计划。 您将需要它。
此外,填写该网格还需要进行大量工作。
剩下的就是我在没有发电机的情况下使用它,并且犯了一些教育上的错误。
如果要使用列表列表:
row = [None for i in range(0,nc+1)]
grid = [row for i in range(0,nr+1)]
然后,这会为您提供一个列表,其中填充了“无”。
>>> grid
[[None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None]]
好的,所以放入列标题:
>>> for ch in range (1,nc+1):
... grid[0][ch] = raw_input("Header, Column {}".format(ch))
...
Header, Column 111
Header, Column 222
Header, Column 333
>>> grid
[[None, '11', '22', '33'], [None, '11', '22', '33'], [None, '11', '22', '33'], [None, '11', '22', '33']]
呵呵,那为什么不行呢?
>>> grid[0][3]="steve"
>>> grid
[[None, '11', '22', 'steve'], [None, '11', '22', 'steve'], [None, '11', '22', 'steve'], [None, '11', '22', 'steve']]
哦耶。
臭虫
import copy
row = [None for i in range(0,nc+1)]
grid = [copy.deepcopy(row) for i in range(0,nr+1)]
>>> for ch in range (1,nc+1):
... grid[0][ch] = raw_input("Header, Column {}: ".format(ch))
...
Header, Column 1: 11
Header, Column 2: 22
Header, Column 3: 33
>>> grid
[[None, '11', '22', '33'], [None, 5, None, None], [None, None, None, None], [None, None, None, None]]
(忽略5,那是我正在测试的)
然后是行:
>>> for rh in range(1,nr+1):
... grid[rh][0] = raw_input("Row Header: {} ".format(rh))
...
Row Header: 1 11
Row Header: 2 22
Row Header: 3 33
>>> grid
[[None, '11', '22', '33'], ['11', 5, None, None], ['22', None, None, None], ['33', None, None, None]]
因此,现在您用数据填充数据(作为练习,因为它很明显,因此保留)。
我自由地将所有整数保留为字符串,因为您表现出将它们连接在一起的趋势。
如果您真的想要一个可转置的2D数组,那么最痛苦(且功能非常强大)的解决方案是使用numpy数组。 如果尚未安装numpy,则必须安装,但是由于您没有为扩展库指定任何限制,因此我认为此解决方案是可以接受的。
数组索引从0开始,仅接受整数。 有一些方法可以使数组具有自定义索引,例如23, 54, 34, 75
而不是0, 1, 2, 3
。 如果您决定numpy.array
并重写其许多方法, 则可能比预期的要复杂得多 。
相反,我提供了一种创建包装器类的解决方案,该包装器类可以处理您的自定义索引,但不能切片(无论如何,这可能对您来说都是废话)。 在后台,当您请求“ 6523”时,它将把它分成2位数字的字符串“ 65”和“ 23”,然后在行/列列表中查找它们的位置。 在这种情况下,它将是(0,0)。 现在,您可以将该索引用于数组以获取所需的元素。 查找元素的索引的方法相反。 我们绝不会直接与数组结构进行交互,因此无需重写其任何方法。
import numpy as np
class CustomIndexTable:
def __init__(self, rows, columns, elements):
self.rows = rows
self.columns = columns
self.data = np.array(elements, dtype=object)
self.data = self.data.reshape((len(rows), len(columns)))
def __getitem__(self, index):
x, y = index[:2], index[2:]
return self.data[self.rows.index(x),self.columns.index(y)]
def __setitem__(self, index, element):
x, y = index[:2], index[2:]
self.data[self.rows.index(x),self.columns.index(y)] = element
def _where(self, element):
x, y = np.where(self.data == element)
return self.rows[x] + self.columns[y]
def transpose(self):
self.rows, self.columns = self.columns, self.rows
self.data = self.data.T
def where(self, sequence):
elements = []
start = 0
for end in xrange(1, len(sequence)+1):
if sequence[start:end] in self.data:
elements.append(sequence[start:end])
start = end
return ''.join(self._where(e) for e in elements)
def input_matrix_data(text):
return raw_input(text).split()
col_indices = input_matrix_data("Column indices: ")
row_indices = input_matrix_data("Row indices: ")
data = input_matrix_data("All data, sorted by row: ")
table = CustomIndexTable(row_indices, col_indices, data)
您不希望用户在输入新元素时重复表索引,例如对(65,23)和(65,54)重复65。 您可以简单地要求用户一次输入列索引和行索引,稍后我们将构建各个表的坐标。 对于数据,让用户一次输入所有内容,就像读一本书中的几行一样,即从左到右逐行。 对于所有输入,用户应使用空格分隔各个成员。 例如,当输入列索引时,他应该写
23 54 34 75
和数据
AM h 9 C 56 in 13 ok
将数据保存在一维列表中后,我们可以将它们放入数组中,并以每行指定的列数将其重塑为二维。
该类的结构对功能进行了一些假设,这些假设是您的问题所隐含的。
list.index()
或numpy.where()
可能不会像您期望的那样表现。 这种假设是有道理的,因为使用表似乎是为了进行加密/解密,因此,每个元素都应该唯一地映射到另一个元素。 构建完表格后,您可以查看数据(不要直接编辑数组!),
>>> table.data
array([['AM', 'h', '9', 'C'],
['56', 'in', '13', 'ok']], dtype=object)
访问特定元素,
>>> table['7834']
'13'
为一个元素设置一个新值,
>>> table['7834'] = 'B'
>>> table['7834']
'B'
找到元素所在的位置,
>>> table.where('9') # this should work equally well for '9C'
'6534'
或永久转置数组。
>>> table.transpose()
>>> table.where('9')
'3465'
最后,您可以在满足您的需要时向此类添加更多方法,例如,在创建表之后添加/删除整行元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.