循环遍历字符串

Cycle through string

我需要能够使用模运算符循环遍历一串字符,以便每个字符都可以传递给一个函数。这是一个简单的问题,我知道,但我对如何去做感到非常困惑。这是我所拥有的,但它给了我错误 "TypeError: not all arguments converted during string formatting"。如有任何建议,我们将不胜感激。

key = 'abc'
def encrypt(key,string):
    c = ''
    for i in range(0,len(string)):
        t = (key)%3
        a = XOR(ord(string[i]),ord(t))
        b = chr(a)
        c = c + b
    return(c)

成分

这里有一些要素可以帮助您以简洁的方式编写 encrypt 函数:

  1. 可以直接遍历字符串的字符:

    >>> my_string = 'hello'
    >>> for c in my_string:
    ...     print(c)
    ...
    h
    e
    l
    l
    o
    
  2. 您可以使用标准库的 itertools 模块中的 cycle 函数循环遍历任何可迭代对象(例如,字符串):

    >>> from itertools import cycle
    >>> for x in cycle('abc'):
    ...     print(x)
    ...
    a
    b
    c
    a
    b
    c
    a
    # goes on infinitely, abort with Ctrl-C
    
  3. 可以使用zip函数同时迭代两个序列:

    >>> for a, b in zip('hello', 'world'):
    ...     print(a, b)
    ...
    h w
    e o
    l r
    l l
    o d
    

    Edit:正如 kichik 所建议的,您还可以使用 itertools.izip,这在处理非常大的输入字符串时很有用。

  4. 您使用 ^ 运算符计算两个数字的 xor

    >>> 5 ^ 3
    6
    
  5. 您可以使用 join 函数将一系列单独的字符串连接成一个字符串:

    >>> ''.join(['hello', 'how', 'are', 'you'])
    'hellohowareyou'
    
  6. 您可以使用所谓的 生成器表达式 join 提供数据,这类似于 for 循环,但是单个表达式:

    >>> ''.join(str(x+5) for x in range(3))
    '567'
    

综合起来

from itertools import cycle, izip

def encrypt(key, string):
    return ''.join(chr(ord(k) ^ ord(c))
                   for k, c in izip(cycle(key), string))

您可以(可能应该)在不使用 range() 的情况下遍历字符,并且您需要在 运行 mod 之前对每个字符进行 运行 ord()它,因为 % 运算符对字符串有其他含义。这应该有效:

key = 'abc'
for c in key:
    print XOR(ord(c), ord(c) % 3)

您可以使用 itertools.cycle() 循环键和 itertools.izip() 来轻松组合两者。

import itertools

def encrypt(key, string):
  keyi = itertools.cycle(key)
  result = ''
  for k, v in itertools.izip(keyi, string):
    a = ord(v) ^ ord(k)
    result += chr(a)
  return result

然后像这样使用它:

>>> encrypt('\x00', 'abc')
'abc'
>>> encrypt('\x01', 'abc')
'`cb'

您遇到有关格式化的错误,因为 % 不是字符串的模运算符。它用于格式化字符串。您可能打算使用这样的东西:

key[i%3]