2013-01-05 73 views
1

我是新來的Python和努力頗有幾分拿到這是怎麼回事。 這是我的任務:如何在Python中搜索嵌套列表網格並給出字母座標?

的六個字母的密碼是編碼一個祕密消息 既包括替代和換位的方法。加密通過 開始從0到9(總共36個符號),隨機填充66網格從A字母表字母A到Z 和數字。該網格必須是消息的發送者和接收者都知道的 。網格的行和 列標有字母A,B,C,D,E,F。

編寫一個實現六字母密碼方法的Python程序。 你的程序應該: 1.創建一個6x6的網格,並用字母和在第一段所述數字隨機填充它,然後提示用戶輸入 祕密信息。 2.在用戶輸入祕密消息後,顯示6x6網格和生成的密文。 3.提示用戶輸入密文以顯示原始消息。它是確定要求用戶的 密文的每兩個字母用空格或逗號分隔。

我一直在努力的是如何通過嵌套列表搜索已輸入的隨機放置的字母並給出座標。也不會座標用數字來給出,即0,1,而不是字母,即A,B 我想我可以管理的編碼和解碼,一旦我對如何使用此嵌套列表的想法。

這是到目前爲止我的代碼:

grid = [["Z","9","G","Q","T","3"], 
    ["Y","8","F","P","S","2"], 
    ["X","7","E","O","R","1"], 
    ["W","6","D","N","M","0"], 
    ["V","5","C","L","K","U"], 
    ["J","4","B","I","H","A"]] 

def main(): 
    print("Welcome to the sixth cipher") 
    print("Would you like to (E)Encode or (D)Decode a message?") 
    operation = input() 

    if(operation == "E"): 
     encodecipher() 
    elif(operation == "D"): 
     decodecipher() 
    else: 
     print("Sorry, input not recognised") 

def encodecipher(): 
    print("Please enter a message to encode:") 
    messagetoencode = input() 



def decodecipher(): 
    print("Decode Test") 
    rowcolumn() 


def rowcolumn(): 
    pass 

main() 
+0

你是Java開發人員嗎? –

+0

所以 - 這是否意味着如果我想用純文本'ZZZ'使用該網格 - 我得到密文'AAAAAA'(或類似的?) –

回答

2

您可以使用Python的枚舉遍歷值,並提供每個值的索引位置,當您去:

grid = [["Z","9","G","Q","T","3"], 
    ["Y","8","F","P","S","2"], 
    ["X","7","E","O","R","1"], 
    ["W","6","D","N","M","0"], 
    ["V","5","C","L","K","U"], 
    ["J","4","B","I","H","A"]] 

search = 'D' 

for rownum, row in enumerate(grid): 
    for colnum, value in enumerate(row): 
     if value == search: 
      print "Found value at (%d,%d)" % (rownum, colnum) 

可以適應這種到您的選擇的函數的結構,如下面(如果在網格值是唯一的):

def findvalue(grid, value): 
    for rownum, row in enumerate(grid): 
     for colnum, itemvalue in enumerate(row): 
      if itemvalue == value: 
       return (rownum, colnum) 
    raise ValueError("Value not found in grid") 

由於這將引發ValueError如果找不到該值,你必須在你的調用代碼來處理這個問題。

然後,如果您需要在0索引的行數和列數之間的映射,以字母A ... F,你可以這樣做:

def numbertoletter(number): 
    if number >= 0 and number <= 26: 
     return chr(65 + number) 
    else: 
     raise ValueError('Number out of range') 

,這將給你如下:

>>> numbertoletter(0) 
'A' 
>>> numbertoletter(1) 
'B' 

全部放在一起給你:

value = 'B' 
row, col = map(numbertoletter, findvalue(grid, value)) 
print "Value '%s' found at location (%s, %s)" % (value, row, col) 
+0

謝謝,這是一個很好的幫助 –

+0

爲您增加了一些更多的信息。請確保'接受'答案。 –

1

這是一種簡單的方式來獲得一個字符的座標在網格:

def find_pos(s): 
    for i, j in enumerate(grid): 
     try: 
      return i, j.index(s) 
     except ValueError: 
      continue 
    raise ValueError("The value {0!r} was not found.".format(s)) 


>>> find_pos("O") 
(2, 3) 
+1

首先,縮進是關閉的,而且這對於'grid'上額外的'index()'調用是非常低效的,意味着你在每個循環中循環一次。改用'enumerate()'。另外,千萬不要使用'except:' - 你應該捕獲明顯的異常。 -1現在。 –

+0

這也推測每個元素都是唯一的。 –

+1

@Lattyware這似乎是相當合理的考慮到生成網格的要求......? –

4

我知道你這樣做是對學習/做作業的目的,但我會指出這一點的東西讓你記住以後承擔。想象一下你擁有的36件物品(它恰好可以表現爲6x6) - 或者更明確 - 你有一個角色 - >座標,並且dict對於做這件事非常有用,它...

from string import ascii_uppercase, digits 
from random import shuffle 
from itertools import product 

# build 36 items list and randomise it 
chars = list(ascii_uppercase + digits) 
shuffle(chars) 

# alternatively, use your existing grid: 
from itertools import chain 
chars = list(chain.from_iterable(grid)) 
# ... 


# Create char -> (coords) 
lookup = dict(zip(chars, product('ABCDEF', repeat=2))) 
# Swap over so (coords) -> char 
rev_lookup = {v: k for k,v in lookup.iteritems()} 
+0

將列表列表轉換爲字典似乎是唯一合理的事情。將OP列表的列表轉換爲字典,而不是從頭開始生成,這是我在答案中唯一想念的。無論如何。 – Jaime

+1

@Jaime在給出現有的LoLs的基礎上做一個說明 –