【问题标题】:Caesar Shift on list elements using list comprehension使用列表理解对列表元素进行 Caesar Shift
【发布时间】:2015-02-22 00:12:56
【问题描述】:

我对 Python 很陌生,遇到了障碍。是否可以使用列表推导对列表中单词的每个字母进行移位?另外,我如何以类似的列表理解方式使用 ord() 和 chr() ?

到目前为止,我有以下代码:

def shift( file1="file1.txt",  file2 ="file2.txt"):

    key = int(input("Enter shift key: ")) 

    with open(" file1. txt") as readfile:

             lines = readfile.readlines()

             lines = [words.lower() for words in lines] 

             lines = [ words.split(" ")  for words in lines] 

我现在只需要执行实际的轮班,但我很难过:/

【问题讨论】:

    标签: python list list-comprehension


    【解决方案1】:

    这是一个使用推导式的简单凯撒变换:

    >>> string = 'CaesarShift'; shift=3
    >>> ''.join(chr(ord('a') + (ord(c)-ord('a')+shift) % 26) for c in string)
    'zdhvdupkliw'
    

    这说明了这个概念,但没有尝试处理空格或标点符号。

    可逆性

    >>> new = ''.join(chr(ord('a') + (ord(c)-ord('a')+shift) % 26) for c in string.lower())
    >>> ''.join(chr(ord('a') + (ord(c)-ord('a')-shift) % 26) for c in new)
    'caesarshift'
    

    【讨论】:

      【解决方案2】:

      您可以使用str.join,从word_list 中的每个word 中迭代每个ch/character,您可以使用任何公式来创建您的密码。

      word_list = ["Foo","Bar","Foobar"]
      print(["".join(chr(ord(ch) + 10) for ch in word.lower()) for word in word_list ])
      
      ['pyy', 'lk|', 'pyylk|']
      

      【讨论】:

      • 这个方法给出了一个错误 unresolved reference to word
      【解决方案3】:
      1. Wrap Around:Caesar Shift 是一种环绕式移位密码,因此您必须有一个算法来环绕字符串。

        如果您将字母视为数字,则可以将字母写为 [0, 1 ... 25],即range(26)

        如果您对此进行 10 的凯撒移位,您将得到:[10, 11 ... 25, 26 ... 35]。

        字符 26 不在字母表中。您需要将其更改为 0。然后将字符 27 更改为 1,依此类推。因此,您正在寻找的转换(如果字母表从 0 到 25 排列)是 mod( letterValue + 10, 26)

      2. 但是,字母不是从 0 开始的,所以您必须先减去 ord('a') 的值,然后再添加。

        上述表达式中的letterValue 就是:ord(ch) - ord('a')。所以把前面的表达式改成(chr(ch) - ord('a') + 10) % 26

        然后使用:chr((chr(ch) - ord('a') + 10) % 26 + ord('a')) 将其改回。

        由于ord('a')96,您可以通过使用:chr((chr(ch) - 96 + 10)%26 + 96),即chr((chr(ch)-86)%26 + 96) 来加快这个过程

      3. 非字母字符:?! 等字符将转换为什么?这些通常不会改变。您可以提供 if 条件并检查请求的字符是否在 string.ascii_lowercase 中。

        类似:

        from string import ascii_lowercase as lowerLetters
        
        def toCaesar(ch):
        
            if ch in lowerLetters: 
                return chr((chr(ch) - 86)%26 + 96)
            else:
                return ch
        

      其余的我想你已经有了。

      【讨论】:

        猜你喜欢
        • 2016-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-20
        • 1970-01-01
        相关资源
        最近更新 更多