我意识到在任何地方使用功能范例并不总是会产生非常易读的代码 - 下面的代码段就是我正在做的一个练习。我要做的是如下: -
给定字符串(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
我做错了什么?
我是如何尝试使用函数式编程解决问题的?
答案 0 :(得分:4)
我使用zip
xor 2个字符串:
l = [ord(s1) ^ ord(s2) for s1,s2 in zip(str1,str2)]
答案 1 :(得分:1)
将初始值设定项传递给reduce
就像这样
reduce(add, (map(xor_char, string_one, string_two) if string_one != string_two else ""), "")
答案 2 :(得分:1)
好的,据我所知,如果不相等,你需要将字符串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列表,然后我们检查l元素是否等于S(if l is not S else S
),如果这有效,我们会做xor-ing part。
好的,我玩过你的代码。发电机内部问题减少。如果字符串相同,它会为您提供空列表。你可以通过将if
移动到lambda而不是reduce来解决这个问题。像这样:
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', '']