算法:用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 x in A for y in B)。

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

用*,即product(*ls)。

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

Python实现:

 1 #-*- coding:utf-8 -*-
 2 __author__ = ‘Administrator‘
 3
 4 from itertools import product
 5 import time
 6
 7 combine=["08","124","1235","236","1457","24568","3569","478",
 8          "57890","689"]
 9
10 def get_pin(observe):
11     return ["".join(p) for p in product(*(combine[int(d)] for d in observe))]
12
13 def get_pin2(observe):
14     comb=[]
15     li=[]
16     for d in observe:
17         comb.append(combine[int(d)])
18     for p in product(*comb):
19         li.append("".join(p))
20     return li
21
22 if __name__=="__main__":
23     t0=time.time()
24     for i in range(10000):
25         get_pin("1357")
26     t1=time.time()-t0
27     print(t1)
28     print("-"*100)
29     t0=time.time()
30     for i in range(10000):
31         get_pin2("1357")
32     t1=time.time()-t0
33     print(t1)

输出时间对比:

0.6550376415252686
----------------------------------------------------------------------------------------------------
0.7860448360443115

时间: 2024-11-05 11:35:02

算法:用itertools.product()简化嵌套for循环的相关文章

用itertools.product简化嵌套for循环

今天这一题叫做"偷瞄到的密码": 警察跟踪一名窃贼来到了一个仓库门前.仓库的密码锁盘如下: 1 2 3 4 5 6 7 8 9 0 窃贼输入密码后进了门.警察"觉得"自己看到了密码比如1357,但是也有可能是相邻的数字(相邻仅包括正上下左右,不包括对角线),比如第一位不是1,而是相邻的4和2(不包括5). 可能的密码是哪些组合呢? 这道题目可以抽象成: 1. 0-9各自都对应了一组相邻数字 现给定一个数字串: 2. 对数字串中的每个数字,找到对应的相邻数组 3. 计

SQL中使用WITH AS提高性能,使用公用表表达式(CTE)简化嵌套SQL

一.WITH AS的含义     WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分. 特别对于UNION ALL比较有用.因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可.如果WITH AS短语所定

使用公用表表达式(CTE)简化嵌套SQL

一.WITH AS的含义     WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分. 特别对于UNION ALL比较有用.因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可.如果WITH AS短语所定

谈谈嵌套for循环的理解

谈谈嵌套for循环的理解     说for的嵌套,先说一下一个for循环的是怎么用的.      这次的目的是为了用for循环输出一个乘法口诀表,一下就是我的一步步理解.    一.   语法:            for(表达式1;表达式2;表达式3){                java语句;            }                表达式1是初始化表达式,最先执行,只执行一次.        表达式2必须是boolean类型的表达式.        for循环开始执行

递归、嵌套for循环、map集合方式实现树形结构菜单列表查询

有时候, 我们需要用到菜单列表,但是怎么样去实现一个菜单列表的编写呢,这是一重要的问题. 比如我们需要编写一个树形结构的菜单,那么我们可以使用JQuery的zTree插件:http://www.treejs.cn/v3/main.php#_zTreeInfo 例如现在需要编写一个这样的菜单列表.那么就可以使用JQuery的zTree插件. 先看一下数据库表结构. CREATE TABLE `permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `

机器学习入门-混淆矩阵-准确度-召回率-F1score 1.itertools.product 2. confusion_matrix(test_y, pred_y)

1. itertools.product  进行数据的多种组合 intertools.product(range(0, 1), range(0, 1))  组合的情况[0, 0], [0, 1], [1, 0], [1, 1] 2. confusion_matrix(test_y, pred_y)  # 构造混淆矩阵 混淆矩阵是TP(正的预测成正的), FP(正的预测成负的), TN(负的预测成负的), FN(负的预测成正的) 从混淆矩阵中,我们可以很清楚的看出这个信息,这是一个信用欺诈的案例,

列表中使用嵌套for循环[i*j for i in range(3) for j in range(3)]

利用嵌套for循环形成一个新列表 [i*j for i in range(3) for j in range(3)]相当于如下代码 li=[] for i in range(3): for j in range(3): print(i*j) li.append(i*j) print(li) 结果和[i*j for i in range(3) for j in range(3)]的结果一样都是: [0, 0, 0, 0, 1, 2, 0, 2, 4] 以上就是利用嵌套for循环形成一个新列表是怎么

算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer

习题2-1 位数 输入一个不超过109的正整数,输出它的位数.例如12735的位数是5.请不要使用任何数学函数,只用四则运算和循环语句实现. #include<stdio.h> int main(void) { int n; int digit = 0; scanf("%d",&n); while(n) { n = n / 10; digit++; } printf("%d\n", digit); return 0; } 习题2-2 水仙花数 输

&lt;09&gt; for循环的嵌套+for循环嵌套应用:打印图形+ 按要求打印图形+

for循环的嵌套: 1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) { 4 //打印出矩形的“*” 5 //控制打印了5行 6 //第一种理解方式:把打印一行的代码,执行了5次 7 for (int j=0; j<5; j++) { 8 //打印一行 * ,有5个 9 10 for(int i=0;i<5;i++){ 11 printf("*\t"); 12 } 13 printf