[英]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.