1.字符串处理
将字符串中的数字替换成其两倍的值,例如:
修改前:"AS7G123m (d)F77k"
修改后:"AS14G246m (d)F154k"
个人思路:先用正则表达式将其中的数字匹配出来进行乘2操作,然后将字符串根据其中的数字进行切割,得到一个字符列表,最终将乘以2后的数字和原有的字符进行拼接得到最后的结果。(我脑子比较笨,想不到别的,如果您有更好更简便的方法,希望可以分享一下!)
1
import
re
2
3
text =
"
AS7G123m (d)F77k
"
4
nums = re.findall(r
'
(\d+)
'
, text)
#
取出字符串中数字
5
double_nums = [2 * int(i)
for
i
in
nums]
#
乘以2
6
the_str = []
#
字符列表
7
for
i
in
nums:
8
the_str.append(text.split(i, 1
)[0])
9
text = text.split(i, 1)[1
]
10
result =
""
#
结果
11
for
i
in
range(len(double_nums)):
12
result += the_str[i] +
str(double_nums[i])
13
result +=
text
14
print
(result)
2.Python传参是值传递还是引用传递?
答案是Python中传递参数是引用传递,那么要证明是引用传递呢?可以参考下面这个例子:
1
def
f(x):
2
print
(id(x))
3
4
5
a = 1
6
print
(id(a))
7
f(a)
8
#
140716760159264
9
#
140716760159264
这里分别打印了两个地址,一个是对象a的地址,一个是传入的参数x的地址,可以看到两个地址是一样的,这也就说明Python中的传参使用的引用传递!需要注意的是: 对于不可变类型,在函数中对其操作并不会对原对象产生影响,但对于可变类型,在函数中对其操作则可能会改变其值 ,如下:
1)传入的参数是不可变类型:
1
def
f(x):
2
x +=
"
666
"
#
这里会创建一个新的对象
3
print
(x)
4
5
6
s =
"
777
"
#
字符串不可变
7
print
(s)
8
f(s)
9
print
(s)
10
11
#
777
12
#
777666
13
#
777
2)传入的参数是可变类型:
1
def
f(x):
2
x.append(4)
#
修改原对象的值
3
print
(x)
4
5
6
s = [1, 2, 3]
#
列表可变
7
print
(s)
8
f(s)
9
print
(s)
10
11
#
[1, 2, 3]
12
#
[1, 2, 3, 4]
13
#
[1, 2, 3, 4]
3.浅拷贝与深拷贝的那些事
在Python中,浅拷贝与深拷贝是一定要分清楚的!对于浅拷贝和深拷贝,可以这么理解:
1) 浅拷贝:创建一个对象,但其中包含的是原对象中所包含项的引用,如果用引用的方式修改了其中的对象,就会对原对象进行改变。
2) 深拷贝:创建一个对象,并且递归复制原对象中所包含的对象,此时修改数据不会对原对象产生影响。
在下面的代码中包含了赋值、浅拷贝和深拷贝,在Python中赋值即引用对象,所以对c操作也就是对原对象a进行操作,对于浅拷贝对象b和d,对其中的引用进行操作会改变对a中的对象,而对深拷贝对象e进行操作就与原对象a无关了。
1
import
copy
2
3
a = [1, [2], 3
]
4
b = a[:]
#
使用切片操作,浅拷贝
5
c = a
#
赋值操作,即引用
6
d = a.copy()
#
浅拷贝
7
e = copy.deepcopy(a)
#
深拷贝
8
9
b.append(4
)
10
c.append(5
)
11
d.append(6
)
12
d[1].append(2
)
13
e.append(7
)
14
e[1].append(3
)
15
16
print
(a)
#
[1, [2, 2], 3, 5]
17
print
(b)
#
[1, [2, 2], 3, 4]
18
print
(c)
#
[1, [2, 2], 3, 5]
19
print
(d)
#
[1, [2, 2], 3, 6]
20
print
(e)
#
[1, [2, 3], 3, 7]
4.Python一行式能干嘛?
下面是一些Python一行式的示例,从中可以看出Python是非常简洁和强大的!
1)一行代码输出一百以内的奇数:
print([x for x in range(100) if x % 2])
2)一行代码求水仙花数:
print([x for x in range(100, 1000) if int(str(x)[0])**3 + int(str(x)[1])**3 + int(str(x)[2])**3 == x])
3)一行代码打印九九乘法表:
print("".join(["{} * {} = {}\t".format(x, y, x * y) if x != y else "{} * {} = {}\n".format(x, y, x * y) for x in range(1, 10) for y in range(1, x + 1)]))
4)一行代码实现IP地址转换,如将192.168.12.1转换成0b11000000 10101000 00001100 00000001:
print("0b"+" ".join(("00000000" + bin(int(i)).replace("0b", ""))[-8:] for i in ip.split(".")))
5)一行代码求1到10的和:
from functools import reduce; print(reduce(lambda x, y: x + y, [i for i in range(1, 11)]))
5.下面这段代码的结果是什么?
1
def
mul():
2
return
[
lambda
x: x * i
for
i
in
range(4
)]
3
4
5
print
([m(2)
for
m
in
mul()])
以上这段代码输出的结果是[6, 6, 6, 6],而不是[0, 2, 4, 6]!
产生这个问题的原因在于Python闭包的延迟绑定。这意味着内部函数被调用时,参数的值在闭包内进行查找。所以当mul()返回的函数被调用时,i的值会在返回的函数里查找,而for循环完成后i的值为3,也就是i最终赋值为3。因此,每次返回的函数乘以传入的值就是最后的结果,得到的结果就是[6, 6, 6, 6]。
如果要解决这个问题,可以参考以下方法:
1)使用Python生成器。
1
def
mul():
2
for
i
in
range(4
):
3
yield
lambda
x: x *
i
4
5
6
print
([m(2)
for
m
in
mul()])
2)创造一个闭包,利用默认函数进行绑定。
1
def
mul():
2
return
[
lambda
x, i=i: x * i
for
i
in
range(4
)]
3
4
5
print
([m(2)
for
m
in
mul()])

