Python函数式编程自学习

时间:2013-11-10 16:35:39

标签: python functional-programming

我意识到在任何地方使用功能范例并不总是会产生非常易读的代码 - 下面的代码段就是我正在做的一个练习。我要做的是如下: -

  

给定字符串(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
  • 我做错了什么?

  • 我是如何尝试使用函数式编程解决问题的?

  • 你能想到的任何明显的改进?(改进也必须遵循功能范例 - 我这样做是一个思考练习,而不是在任何项目中)。

3 个答案:

答案 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', '']