2015-03-27 2 views
1

Мне нужно иметь возможность циклически перемещаться по строке символов, используя оператор modulo, чтобы каждый символ мог быть передан функции. Это простой вопрос, я знаю, но я серьезно запутался в том, как это сделать. Вот что я имею, но он дает мне ошибку «TypeError: не все аргументы, преобразованные во время форматирования строки». Мы ценим любые предложения.Цикл через строку

+0

Что вы ожидаете от '' abc '% 3'? –

+0

Я хочу, чтобы он разделил каждый символ в строке так, чтобы они могли быть переданы в ord (t) в x – Tony

ответ

4

Ингредиенты

Вот некоторые ингредиенты, которые помогут вам написать encrypt функции в краткой форме:

  1. Вы можете непосредственно перебрать символы строки:

    >>> my_string = 'hello' 
    >>> for c in my_string: 
    ...  print(c) 
    ... 
    h 
    e 
    l 
    l 
    o 
    
  2. Вы можете циклически перебирать любую итерабельную (например, строку) с помощью функции cycle из itertools модуль стандартной библиотеки:

    >>> 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: в кичик предлагает, вы можете также используйте 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)) 
0

Вы можете (вероятно, должны) перебор символов без использования диапазона(), и вы захотите запустить ord() для каждого символа перед тем, как запустить mod на нем, поскольку оператор% означает что-то еще для строки. Это должно работать:

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

Вы можете использовать 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] 
+0

Ваш последний sentene неверен. '%' действительно используется в форматировании в стиле старого стиля, но также используется как [modulo operator] (https://docs.python.org/2/reference/expressions.html#binary-arithmetic-operations). – BioGeek

+0

Вы правы. Я имел в виду только строки. – kichik

Смежные вопросы