作为我学习python之旅的一部分,我正在实施公牛和奶牛
我有一个使用列表理解的工作实现,但我认为使用生成器和reduce()
来解决这个问题可能是一个很好的解决方案 - 最终结果。
所以我有我的发电机:
def bullsandcows(given, number):
for i in range(given.__len__()):
if given[i] == number[i]:
yield (given[i], None)
elif given[i] in number:
yield (None, given[i])
我的减少实施:
(bulls, cows) = reduce(\
lambda (bull, cow), (b, c): \
(bull + 1, cow + 1), bullsandcows(given, number), (0, 0))
其中given
是用户输入,number
是用户猜测的随机生成的数字。
正如您所看到的,这不是一个有效的实现,只会返回yield
ed元组的计数。
我需要的是(bull + 1, cow + 1)
的替代品,我不知道如何构建它。
number
是一个随机生成的数字,例如:1234
given
,例如:8241
bullsandcows(given, number)
的结果为:[('2', None), (None, '4'), (None, '1']
reduce
的结果应为:(1, 2)
,这是第一个元素的所有非None
值的计数和所有非None
的计数第二个元素的值答案 0 :(得分:2)
如果我正确理解了该过程,您需要计算bull
不是None
,以及cow
不是None
的数量:
reduce(lambda (bcount, ccount), (b, c): (bcount + (b is not None), ccount + (c is not None)),
bullsandcows(given, number), (0, 0))
仅当bull
或cow
值不是None
时,才会增加计数器。测试产生一个布尔值,它是int
的子类False == 0
和True == 1
;将整数和布尔值相加得到另一个整数。
由于您正在为它提供非空字符串,您可以将其简化为:
reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)),
bullsandcows(given, number), (0, 0))
我将bullsandcows()
重写为:
def bullsandcows(given, number):
given, number = map(str, (given, number))
for g, n in zip(given, number):
if g == n:
yield (g, None)
elif g in number:
yield (None, g)
e.g。使用zip()
配对given
和number
的数字。
演示:
>>> def bullsandcows(given, number):
... given, number = map(str, (given, number))
... for g, n in zip(given, number):
... if g == n:
... yield (g, None)
... elif g in number:
... yield (None, g)
...
>>> given, number = 8241, 1234
>>> list(bullsandcows(given, number))
[('2', None), (None, '4'), (None, '1')]
>>> reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)),
... bullsandcows(given, number), (0, 0))
(1, 2)
请注意,函数参数中的解包已从Python 3中删除,reduce()
内置已委托给库函数;你的代码肯定只是Python 2。
要使其在Python 3中运行,您需要导入functools.reduce()
并调整lambda以不使用解包:
from functools import reduce
reduce(lambda counts, bc: (counts[0] + bool(bc[0]), counts[1] + bool(bc[1])),
bullsandcows(given, number), (0, 0))