2013-11-10 4 views
2

Я понимаю, что использование функциональной парадигмы во всем мире не всегда приводит к очень читаемому коду - сегмент кода ниже - это то, что я делаю так же, как упражнение. Я пытаюсь сделать следующее: -Самонастройка функционального программирования Python

Учитывая список строк (L) и строку (S) Мне нужно найти L [i]^S. Если S существует в L, не сверьте строки. L [i]^S означало бы xoring байты в одном и том же положении друг с другом.

Вот как я приступил к решению проблемы. Я попытался разбить его на самую простую форму - например, на двух символах. Если один из входов не будет символом, я верну его "" (я не мог придумать лучшего способа сделать это).

xor_char = lambda x, y: (chr(ord(x)^ord(y)) if x and y else "") 
assert xor_char(None, "a") == "" 
assert xor_char("a", " ") == "A" 

Далее, я пытаюсь написать код для строк.

from operator import add 
xor_string = lambda string_one, string_two: reduce(add, (map(xor_char, string_one, string_two) if string_one != string_two else "")) 
assert xor_string("asdf", "asdfg") == "\x00\x00\x00\x00" 
assert xor_string("asdf", " ") == "ASDF" 

Затем, наконец, я пытаюсь выполнить это в списке строк и строки.

xor_list_string = lambda l, s: map(xor_string, l, [s]*len(l)) 
print xor_list_string(a_list, a_string) 

я получаю ошибку следующим образом на выполнении выше линии: -

Traceback (most recent call last): 
    File "2.py", line 26, in <module> 
    main() 
    File "2.py", line 23, in main 
    analyze(all_lines, all_lines[-1]) 
    File "2.py", line 18, in analyze 
    print xor_list_string(a_list, a_string) 
    File "2.py", line 17, in <lambda> 
    xor_list_string = lambda l, s: map(xor_string, l, [s]*len(l)) 
    File "2.py", line 11, in <lambda> 
    xor_string = lambda string_one, string_two: reduce(add, (map(xor_char, string_one, string_two) if string_one != string_two else "")) 
TypeError: reduce() of empty sequence with no initial value 
  • Что я делаю неправильно?

  • Есть ли что-то не так с тем, как я пытаюсь решить проблему, используя функциональное программирование?

  • Любые очевидные улучшения, о которых вы можете подумать (улучшения должны были бы соответствовать функциональной парадигме тоже - я делаю это как мысленное упражнение, а не в каком-либо проекте).
+1

Pass инициализатор (третий параметр) для 'reduce' задать поведение, когда итерация пуста. http://docs.python.org/2/library/functions.html#reduce –

+0

@uki Какие значения 'a_list' и' a_string'? – thefourtheye

+0

@ темой фиктивных значений a_list может быть ["asdf", "asdfg", "qwer"], а a_string может быть "qwer". –

ответ

1

Это всегда хорошо, чтобы передать инициализатору в reduce как этот

reduce(add, (map(xor_char, string_one, string_two) if string_one != string_two else ""), "") 
4

Я XOR 2 строки вместе с помощью zip:

l = [ord(s1)^ord(s2) for s1,s2 in zip(str1,str2)] 
1

Ok, далеко, как я вас понимаю необходимо, чтобы каждая строка l в списке строк L была сослана с строкой b, если они не равны. Вы можете использовать список понимание для этого:

In [1]: L = ['a', 'b', 'c', 'd', 'e', 'f'] 
In [2]: S = 'c' 
In [3]: [ chr(ord(l)^ord(S)) if l is not S else S for l in L] 
Out[3]: ['\x02', '\x01', 'c', '\x07', '\x06', '\x05'] 

Мы используем for l in L перебирать список L, то мы проверяем, если я элемент равен S (if l is not S else S) и, если это работает, мы делаем XOR-ную часть.

Хорошо, я играл с вашим кодом. Проблема с внутренним генератором уменьшается. Он дает вам пустой список, если строки идентичны. Вы можете исправить это, переместив if в лямбда вместо сокращения.Как это:

a_list = [ 'as', 'qwe', 'vcs', 'ase', 'wsc', 'ase', 'sa' ] 
a_string = 'sa' 

xor_char = lambda x, y: (chr(ord(x)^ord(y)) if x and y else "") 
assert xor_char(None, "a") == "" 
assert xor_char("a", " ") == "A" 

from operator import add 
xor_string = lambda string_one, string_two: reduce(add, map(xor_char, string_one, string_two)) if string_one != string_two else '' 
assert xor_string("asdf", "asdfg") == "\x00\x00\x00\x00" 
assert xor_string("asdf", " ") == "ASDF" 

xor_list_string = lambda l, s: map(xor_string, l, [s]*len(l)) 
print xor_list_string(a_list, a_string) 

Выход:

['\x12\x12', '\x02\x16', '\x05\x02', '\x12\x12', '\x04\x12', '\x12\x12', ''] 
Смежные вопросы