python - 减少元组列表

标签 python tuples reduce

作为我学习 Python 之旅的一部分,我正在实现 Bulls 和 Cows。
我有一个使用列表理解的工作实现,但我认为使用生成器和 reduce()-ing 最终结果来解决这个问题可能是一个很好的解决方案。

所以我有了我的发电机:

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])

以及我的reduce实现:

(bulls, cows) = reduce(\
    lambda (bull, cow), (b, c): \
        (bull + 1, cow + 1), bullsandcows(given, number), (0, 0))

其中given是用户输入,number是随机生成的数字供用户猜测。

正如您所看到的,这并不完全是一个有效的实现,它只会返回 yielded 元组的计数。

我需要的是(bull + 1,cow + 1)的替代品,我不知道如何构造它。

  • number 是随机生成的数字,例如:1234
  • given 由用户输入,例如:8241
  • bullsandcows(given, number) 的结果将是:[('2', None), (None, '4'), (None, '1']
  • reduce 的结果应该是:(1, 2),它是所有非 None 值的计数第一个元素和第二个元素的所有非 None 值的计数

最佳答案

如果我正确理解了这个过程,你想计算哪些公牛不是,以及有多少不是:

reduce(lambda (bcount, ccount), (b, c): (bcount + (b is not None), ccount + (c is not None)),
       bullsandcows(given, number), (0, 0))

仅当 bullcow 值不为 None 时,才会递增计数器。该测试生成一个 bool 值,它是 int 的子类,其中 False == 0True == 1;将整数和 bool 值相加得到另一个整数。

由于您正在向其提供非空字符串,因此您可以将其简化为:

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)

例如使用 zip()givennumber 的数字配对。

演示:

>>> 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() 内置函数已委托(delegate)给库函数;你的代码绝对只是 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))

关于python - 减少元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23633158/

相关文章:

python - python 模块可以有 __repr__ 吗?

python - 项目 Euler 问题 26 Python 字符串分数限制

python - 在多个类和多个模块中使用全局变量

c++ - 从元组列表中访问单个元组的元素

c++ - 如何解压在 mixins 主机类中传递的一组元组(最终被转发给 mixins)

python - 使用 Colab 访问本地文件夹

python - 从组合两个多索引 dfs 和列索引的元组列表构建字典

Python:减少(字符串列表)-> 字符串

javascript - JavaScript 中 reduceRight 的原生实现是错误的

javascript - JS reduce - 仅对对象中的数组长度求和