【问题标题】:Simplifying Vigenere cipher program in Python用 Python 简化 Vigenere 密码程序
【发布时间】:2016-05-12 20:16:12
【问题描述】:

我有下面的程序,它被传递给另一个函数,该函数简单地打印出原始和加密的消息。我想知道如何简化这个程序,特别是“match = zip”和“change = (reduce(lambda”) 行。如果可以在不使用 lambda 的情况下做到这一点,我该怎么做?

from itertools import cycle

alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]

def vigenereencrypt(message,keyword):
    output = ""    
    match = zip(message.lower(),cycle(keyword.lower()))
    for i in match:
        change = (reduce(lambda x, y: alphabet.index(x) + alphabet.index(y), i)) % 26
        output = output + alphabet[change]
    return output.lower()

【问题讨论】:

    标签: python python-2.7 lambda vigenere


    【解决方案1】:

    两件事:

    1. 你不需要有一个局部变量match,只需循环zip
    2. 您可以在 for 循环定义中拆分两个索引 xy,而不是使用 reduce; reduce 通常用于较大的可迭代对象,由于 i 中只有 2 个项目,因此会增加不必要的复杂性。

    即,您可以将 for 循环定义更改为:

    for x, y in zip(...):
    

    以及您对change 的定义:

    change = (alphabet.index(x) + alphabet.index(y)) % 26
    

    【讨论】:

      【解决方案2】:

      从R Nar所说的开始:

      def vigenereencrypt(message,keyword):
          output = ""
          for x, y in zip(message.lower(), cycle(keyword.lower())):
              change = (alphabet.index(x) + alphabet.index(y)) % 26
              output = output + alphabet[change]
          return output.lower()
      

      我们可以通过使用列表然后加入它来提高效率,而不是添加到字符串中,并且还可以通过注意输出已经是小写:

      def vigenereencrypt(message,keyword):
          output = []
          for x, y in zip(message.lower(), cycle(keyword.lower())):
              change = (alphabet.index(x) + alphabet.index(y)) % 26
              output.append(alphabet[change])
          return "".join(output)
      

      然后我们可以将循环体减少到一行..

      def vigenereencrypt(message,keyword):
          output = []
          for x, y in zip(message.lower(), cycle(keyword.lower())):
              output.append(alphabet[(alphabet.index(x) + alphabet.index(y)) % 26])
          return "".join(output)
      

      ...所以我们可以把它变成一个列表推导:

      def vigenereencrypt(message,keyword):
          output = (
              alphabet[(alphabet.index(x) + alphabet.index(y)) % 26]
              for x, y in zip(message.lower(), cycle(keyword.lower()))
          )
          return "".join(output)
      

      我觉得我们可以用 map(alphabet.index, ...) 做一些事情,但我想不出比列表理解更好的方法。

      【讨论】:

        【解决方案3】:

        你可以用一堆索引而不是 zip 来做到这一点......

        alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
        alphaSort = {k:n for n,k in enumerate(alphabet)}
        alphaDex = {n:k for n,k in enumerate(alphabet)}
        
        def vigenereencrypt(message,keyword):
            output = ""    
            #match = zip(message.lower(),cycle(keyword.lower()))      # zip(a,cycle(b)) Creates [(a[n],b[n%len(b)]) for k in range(len(a)) ] 
            op = ""                                                  # So lets start with  for k in range(len(a))
            for k in range(len(message)):
                op += alphaDex[(alphaSort[message.lower()[k]]+alphaSort[keyword.lower()[k%len(keyword)]])%len(alphabet)]
            return(op)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-16
          • 1970-01-01
          • 2021-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多