用itertools.product简化嵌套for循环

今天这一题叫做“偷瞄到的密码”:

警察跟踪一名窃贼来到了一个仓库门前。仓库的密码锁盘如下:

1 2 3

4 5 6

7 8 9

   0

窃贼输入密码后进了门。警察“觉得”自己看到了密码比如1357,但是也有可能是相邻的数字(相邻仅包括正上下左右,不包括对角线),比如第一位不是1,而是相邻的4和2(不包括5)。

可能的密码是哪些组合呢?

这道题目可以抽象成:

1. 0-9各自都对应了一组相邻数字

现给定一个数字串:

2. 对数字串中的每个数字,找到对应的相邻数组

3. 计算从这些相邻组中各挑一个形成的所有可能组合并输出

实现要点:

1. 上述#3实际上是一个嵌套的多重for循环:

  for 数字串中的每个数字:

    for 该数字相邻数组中的每个数字:

用itertools模块的product方法可以将这个过程简化为一步完成。根据Python手册,product(A, B)的结果是((x,y) for in for in B)。

2. 对于函数或者方法如product(A, B, C, D),如果ABCD在一个列表里ls=[A, B, C, D],如何把ls传给product?

用*,即product(*ls)。

3. product的输出为元组。用join合并元组的所有元素,以字符串的形式输出密码组合。

借用某个最佳实现

from itertools import product

ADJACENTS = ('08', '124', '2135', '326', '4157', '52468', '6359', '748', '85790', '968')

def get_pins(observed):
    return [''.join(p) for p in product(*(ADJACENTS[int(d)] for d in observed))]

暴力破解密码之后,窃贼就是瓮中之鳖啦!

转载于:https://www.cnblogs.com/netoops/p/6875901.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值