【问题标题】:How to search nested list grid and give lettered coordinates in Python? [closed]如何在 Python 中搜索嵌套列表网格并给出字母坐标? [关闭]
【发布时间】:2012-12-19 18:46:16
【问题描述】:

我是 python 的新手,为了实现这一目标,我付出了相当大的努力。 这是我的任务:

六字母密码是一种对秘密信息进行编码的方法, 包括置换和转置。加密开始于 用从 A 到 Z 的字母随机填充 6  6 网格 以及从 0 到 9 的数字(共 36 个符号)。这个网格必须是 消息的发送者和接收者都知道。行和 网格的列标有字母 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()

【问题讨论】:

  • 所以 - 这是否意味着如果我想使用带有纯文本“ZZZ”的网格 - 我得到的密文是“AAAAAA”(或类似的?)

标签: python list matrix grid nested


【解决方案1】:

我知道您这样做是出于学习/家庭作业的目的,但我会指出这一点,以供您稍后记住。更容易将你所拥有的东西想象成 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()}

【讨论】:

  • 将列表列表转换为字典似乎是唯一合理的做法。将 OP 的列表转换为字典,而不是从头开始生成它,是我在您的回答中唯一想念的事情。无论如何 +1。
  • @Jaime 在现有的英雄联盟中记录下如何做到这一点
【解决方案2】:

您可以使用 Python 的 enumerate 来迭代值并随时提供每个值的索引位置:

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)

【讨论】:

  • 谢谢,帮了大忙
  • 为您添加了更多信息。请务必“接受”答案。
【解决方案3】:

这是获取网格中字符坐标的简单方法:

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)

【讨论】:

  • 首先,缩进是关闭的,另外,在grid 上对index() 的额外调用意味着你在每个循环中循环整个事情一次,这确实是低效的。请改用enumerate()。另外,永远不要使用except: - 你应该捕获显式异常。 -1 现在。
  • 这也使得每个元素都是唯一的。
  • @Lattyware 考虑到生成网格的要求,这似乎相当合理......?
  • @JonClements 啊,是的,我没有仔细阅读 - 尽管如此,我的其他不满现在仍然存在。
  • @Lattyware 进行了更改。还有问题吗?
猜你喜欢
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2010-12-12
  • 1970-01-01
相关资源
最近更新 更多