day 12

博客介绍了Python中的递归函数,包含回溯和递推过程,强调结束条件的重要性。还提及二分法的使用条件,介绍了三元表达式、字典生成式、匿名函数,以及常用的内置函数等信息技术相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归函数:

递归函数包括两个过程:

1、回溯:就是一次次的重复的过程,但是在每次重复的过程中要让你的复杂度随着重复的次数一次次降低,还需要最终有一个结束的条件。

2、递推:一次次回溯之后往回推导的过程。

递归函数:

age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
用递归函数实现为:
def get_age(n):            
    if n == 1: #结束条件            
        return 18          
    age = get_age(n-1)+2   
    return age             
age = get_age(5)           
print(age)                 
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,]]]]]]]]]]]]]
# 将列表中的数字依次打印出来(循环的层数是你必须要考虑的点)
1 def get_value(l):
2       for i in l :
3           if type(i) is int :
4               print(i)
5           else:
6               get_value(i)
7 get_value(l)
View Code

递归函数通常不需要考虑回溯的次数,但是结束条件必须考虑。

算法之二分法:

二分法的使用条件:容器类型中的数据必须是按顺序排列的

#二分法
l1 = [1,3,5,12,57,89,101,123,146,167,179,189,345]
def find_num(l,n):
    res = len(l)
    index_mid = res // 2
    if n < l[index_mid]:
        l_right = l[0:index_mid]
        print(l_right)
        find_num(l_right,n)
    elif n > l[index_mid]:
        l_left = l[index_mid:]
        find_num(l_left,n)
        print(l_left)
    else:
        print('find it',n)
find_num(l1,3)

三元表达式:

x = 3
y = 5
value = x if x > y else y
print(value)
if 条件成立则value=左边的值x,条件不成立,则value=右边的值y
python不推荐三元表达式中套三元表达式,只推荐在结果只有两种的条件下使用。
列表生成器:
1 l = ['zhao','qian','sun','li']
2 value = ['{}_yang'.format(name) for name in l]
3 #表示for循环列表l中的元素,按照for前面的格式存放到value列表中
4 print(value)
5 value1 = ['{}'.format(name) for name in value if name.endswith('_yang')]
6 #表示先for循环value类表中的元素,在进行后面的if判断,满足条件的元素按照for前面的格式进行输出
7 print(value1)
View Code
1 l = ['zhao','qian','sun','li']
2 value = ['{}_yang'.format(name) for name in l]
3 #表示for循环列表l中的元素,按照for前面的格式存放到value列表中
4 print(value)
5 value1 = ['{}'.format(name) for name in value if name.endswith('_yang')]
6 #表示先for循环value类表中的元素,在进行后面的if判断,满足条件的元素按照for前面的格式进行输出
7 print(value1)
View Code

字典生成式:

#进行一一对应生成字典
l1 = ['name','password','hobby']
l2 = ['jason','123','DBJ','egon']
d = {}
for i,j in enumerate(l1):
    d[j] = l2[i]
print(d)
l = ['yang','zhao','qian']
#for循环i是列表l的索引,而j是列表l中的元素,满足if的条件之后,按照for前面的格式进行输出生成字典
res = {i:j for i,j in enumerate(l) if i!=1}
print(res)

l[1,2,3,4,5,6]

#这样写不是元组生成式,而是生成器表达式,得到的值是个“老母猪”

res = (i for i in l )

print(res)     #<generator object <genexpr> at 0x000001CBC215B200>

for i in res:

print(i)

匿名函数:

没有名字,临时存在用完就没了

#:前面存放的是形参x,y后面存放的是匿名函数的返回值

# 匿名函数通常不会单独使用,是配合内置函数一起使用

res = (lambda x,y:x+y)(1,2)

print(res)

常用的内置函数:

d = {

    'egon':30000,
'jason':88888888888,
'nick':3000,
'tank':1000
}
print(max(d,key=lambda name:d[name]))
#在不指定key的的情况下会按照字典d的key值进行for循环比较,在指定key后会按照匿名函数lambda得到的值进行for循环比较,本题中也即value值。但返回的是按值比较的到的d中key的值。
#也即按薪资比较返回人名
# map 映射
l = [1,2,3,4,5,6]
print(list(map(lambda x:x*2,l)))
#通过for循环将l中的值传入匿名函数的形参中,最后形成列表
# zip 拉链  # 基于for循环
l1 = [1,2,3]
l2 = ['jason','egon','tank']
l3 = ['a','b','c']
print(list(zip(l1,l2)))
print(list(zip(l1,l2,l3)))
#基于for循环将l1,l2,l3将三个列表中的元素一一对应形成列表中套元组的形式

#reduce 模块
from functools import reduce
l = [1,2,3,4,5,6]
print(reduce(lambda x,y:x+y,l,19))#19是指定的初始值,然后按照for循环将l中的值传给匿名函数进行两两,若不指定初始值,会先从列表中取出两个值。



转载于:https://www.cnblogs.com/yangjiaoshou/p/11177175.html

<think>我们正在讨论的是PHP PDO扩展操作SQLite数据库时,是否可以不使用`execute()`方法执行SQL语句。 根据PDO的工作机制,执行SQL语句主要有两种方式: 1. 使用PDO::exec()方法:用于执行不返回结果集的SQL语句(如INSERT、UPDATE、DELETE等),并返回受影响的行数。 2. 使用PDOStatement::execute()方法:通常与预处理语句(prepared statements)一起使用,可以绑定参数,防止SQL注入,适用于需要多次执行的语句。 但是,用户的问题中提到了“是否可以不用execute()方法”,那么我们需要考虑是否有其他替代方法。 另外,PDO还提供了`query()`方法,用于执行SQL查询并返回一个PDOStatement对象,该对象可以用于获取结果集。但注意,`query()`方法通常用于执行不需要参数绑定的简单查询。 因此,我们可以总结如下: - 如果你不需要预处理(即SQL语句中没有变量,或者你已经通过其他方式安全地拼接了SQL语句),那么可以使用`PDO::exec()`(针对非查询语句)或`PDO::query()`(针对查询语句)来执行SQL语句,而不使用`execute()`。 - 但如果你需要预处理(即SQL语句中有变量需要绑定),则必须使用`PDO::prepare()`方法返回的PDOStatement对象的`execute()`方法。 所以,答案是:在特定情况下(即不需要参数绑定的简单SQL语句)可以不用`execute()`方法,而使用`exec()`或`query()`方法。 下面我们分别举例说明: 1. 使用`exec()`方法执行非查询语句(如CREATE, INSERT, UPDATE, DELETE等): ```php $db = new PDO('sqlite:mydatabase.db'); // 执行一个INSERT语句,不需要参数 $count = $db->exec("INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com')"); echo "插入的行数: " . $count; ``` 2. 使用`query()`方法执行查询语句(SELECT): ```php $db = new PDO('sqlite:mydatabase.db'); $stmt = $db->query('SELECT * FROM users'); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); } ``` 但是,请注意: - `exec()`和`query()`方法都不能用于带参数的SQL语句(除非你手动拼接,但这样有SQL注入风险)。 - 当需要传递参数时,必须使用预处理语句,即先`prepare()`再`execute()`。 因此,在需要防止SQL注入的情况下,我们强烈推荐使用预处理语句(即使用`prepare()`和`execute()`)。 综上所述,可以不用`execute()`方法,但仅限于不需要参数绑定的简单SQL语句。对于需要传递用户输入参数的SQL语句,必须使用预处理语句,也就必须使用`execute()`方法。 引用说明: [^1]: PDO是PHP Date Object(PHP 数据对象)的简称,它是与PHP5.1版本一起发行的,目前支持的数据库包括Firebird、FreeTDS、interbase、MYSQL、MS SQL Server、ODBC、Oracle、Postgre SQL、 SQLite和sybase。有了PDO,不必要使用mysql_*函数、oci_*函数或者mssql_*函数,也不必再为它们封闭数据库操作类,只需要使用PDO接口中的方法就可以对数据库进行操作。在选择不同的数据库时,只需要修改PDO的DSN(数据源名称)。 [^2]: PDO::exec():适合执行一次性的简单SQL语句。PDOStatement::execute():适合多次执行相同的SQL模板,只需更换参数。 下面,我们生成相关问题:</think>### PHP PDO SQLite 是否必须使用 execute() 方法执行 SQL 语句? 在 PHP 的 PDO 扩展中操作 SQLite 数据库时,**可以不用 `execute()` 方法执行 SQL 语句**,但仅限于特定场景。以下是替代方案和适用场景: --- ### 1. **使用 `PDO::exec()` 方法** **适用场景**:执行不需要返回结果集的操作(如 INSERT、UPDATE、DELETE、CREATE TABLE 等)。 ```php $db = new PDO('sqlite:mydb.sqlite'); // 直接执行 SQL 语句 $affectedRows = $db->exec(" UPDATE users SET status = 'active' WHERE last_login > '2023-01-01' "); echo "受影响的行数: " . $affectedRows; ``` **特点**: - 直接执行完整 SQL 字符串 - 返回受影响的行数(整数) - **不支持参数绑定**,需手动处理 SQL 注入风险[^2] --- ### 2. **使用 `PDO::query()` 方法** **适用场景**:执行返回结果集的查询(SELECT 语句)。 ```php $result = $db->query("SELECT * FROM products WHERE price > 50"); foreach ($result as $row) { echo $row['product_name']; } ``` **特点**: - 直接返回 `PDOStatement` 对象 - 可通过循环遍历结果集 - 同样**不支持参数绑定**[^1] --- ### ⚠️ 关键限制与风险 1. **SQL 注入风险** 当 SQL 语句包含用户输入时,必须使用预处理语句(`prepare()` + `execute()`): ```php // ❌ 危险!直接拼接用户输入 $db->query("SELECT * FROM users WHERE email = '{$_POST['email']}'"); // ✅ 安全方案(必须用 execute()) $stmt = $db->prepare("SELECT * FROM users WHERE email = ?"); $stmt->execute([$_POST['email']]); // 参数绑定防注入 ``` 2. **性能差异** - `exec()`/`query()`:每次执行需重新解析 SQL - `prepare()` + `execute()`:SQL 模板只需解析一次,适合重复执行[^2] --- ### 最佳实践建议 | **场景** | **推荐方法** | **原因** | |------------------------------|----------------------------|------------------------------| | 执行简单 DDL 语句 | `PDO::exec()` | 无需结果集,简洁高效 | | 静态查询(无用户输入) | `PDO::query()` | 直接获取结果集 | | 含动态参数的用户输入 | `prepare()` + `execute()` | 唯一安全的参数绑定方式 | | 批量操作(如循环插入数据) | `prepare()` + 循环`execute()` | 模板复用提升性能[^2] | --- ### 结论 虽然 `exec()` 和 `query()` 可在特定场景替代 `execute()`,但**涉及用户输入时,必须使用预处理语句(`prepare()` + `execute()`)**。这是防止 SQL 注入的唯一可靠方式,也是 PDO 的核心安全特性[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值