Python03-04

在上一篇博客说了那么多废话,现在就来整点干货。
1.python采用的基于值得内存管理方式,如果为不同变量赋值为相同值,这个值在内存中只有一份,多个变量将指向同一个地址。

>>> x=8
>>> id(x)
1626762480
>>> y=8
>>> id(8)
1626762480
>>> x=[1,2,3]
>>> id(x[0])
1626762256
>>> id(x[1])
1626762288
>>> 

2.字符串界定前面加字母r表示原始字符串,其中得特殊字符串不进行转义,但字符串得最后一个字符不能是\。原始字符串主要用于正则表达式、文件路径或者URL的场合。

>>> path = "c:\swapfile.sys\note.txt"
>>> print(path)
c:\swapfile.sys
ote.txt
>>> path = r'c:\swapfile.sys\note.txt'
>>> print(path)
c:\swapfile.sys\note.txt
>>> 

3.python内部把true当1处理,把false当0处理。
4.python中is用来测试两个对象是否是同一个,如果是则True否则False。

>>> 3 is 3
True
>>> x=[0,1,2]
>>> x[0] is x[1]
False
>>> x=[1,2,3]
>>> y=[1,2,3]
>>> x is y
False
>>> x[1] is y[1]
True

5.逻辑运算符and和or具有惰性求值特点

>>> 3>5 and a>1
False
>>> 5>3 and a>1
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    5>3 and a>1
NameError: name 'a' is not defined
>>> 5>3 or a>1
True

所谓的惰性就是5>3是True,因此没有对后面的表达式进行判断。
6.在python中逗号并不是运算符,只是一个普通分隔符。

>>> 'a' in 'b','a'
(False, 'a')
>>> 'a' in ('b','a')
True
>>> 3 == 5,5
(False, 5)

6.列表中包含的是元素值得引用,而不是直接包含元素值。如果是直接修改序列变量得值,则与python普通变量得情况是一样得,如果是通过下标来修改序列中元素得值或通过可变序列对象自身提供得方法来增加和删除元素时,序列对象在内存中得起始地址是不变得,仅仅是被改变值得元素地址发生变化,这就是所谓的“原地操作”。

>>> a=[1,2,3]
>>> print(id(a))
1898069457224
>>> a.append(5)
>>> print(id(a))
1898069457224

7.当使用*运算符将包含列表的列表重复并创建新列表时,并不创建元素的复制,而是创建已有对象的引用。因此当修改其中一个值时,相应的引用也会被修改。

>>> x=[[None]*2]*3
>>> x
[[None, None], [None, None], [None, None]]
>>> x[0][0]=5
>>> x
[[5, None], [5, None], [5, None]]
>>> x=[[1,3,4]]*3
>>> x
[[1, 3, 4], [1, 3, 4], [1, 3, 4]]
>>> x[0][2]=5
>>> x
[[1, 3, 5], [1, 3, 5], [1, 3, 5]]
>>> 

8.在删除列表元素时,Python会自动对列表内存进行收缩并移动列表元素以保证所以元素之间没有空隙,增加列表元素时也会自动扩展内存并列元素进行移动以保证元素之间没有空隙。每当插入或删除一个元素以后,该元素位置后面所有元素的索引就都改变了。
9.切片是Python序列的重要操作之一,适用于列表、元组、字符串、range对象类型等。切片使用2个冒号分割的3个数字来完成,第一个数字表示切片的开始位置(默认为0),第二个数字表示切片截止(但不包含)位置(默认为列表长度),第三个数字表示切片的步长(默认为1),当步长省略时可以顺便省略最后一个冒号。
切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性。

>>> a=[1,1,3,4,5,4,5]
>>> a[10]
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    a[10]
IndexError: list index out of range
>>> a[0:100:1]
[1, 1, 3, 4, 5, 4, 5]
>>> a[100:]
[]

10.切片返回的是列表元素的浅复制

>>> aList = [1,3,5]
>>> bList = aList
>>> bList[1]=10
>>> a
>>> aList
[1, 10, 5]

所谓的浅复制是指生成一个新的列表,并且把原列表中所有元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样不可变类型的数据,一般是没有问题的。如果原列表中包含列表之类的可变数据类型,由于浅复制时会把子列表的引用复制到新列表中,这样修改任何一个都会影响另外一个。

>>> aList = [1,3,5]
>>> bList = aList[:::]
SyntaxError: invalid syntax
>>> bList = aList[::]
>>> aList == bList  #两个列表元素相同
True
>>> id(aList)==id(bList)
False
>>> bList[1]=10
>>> aList
[1, 3, 5]

11.生成器推导式的结果是一个生成器对象。使用生成器对象的元素时,可以根据需要将其转化成列表或元组,也可以使用生成器对象__next__()方法或内置函数next()进行遍历,或者直接将其作为迭代器对象来使用。
生成器对象具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理场合。
不管使用哪种方法访问生成器对象,都无法再次访问已访问过的元素。

>>> g = ((i+2)**2 for i in range(10))
>>> g
<generator object <genexpr> at 0x00000250E0CDF888>
>>> tuple(g)
(4, 9, 16, 25, 36, 49, 64, 81, 100, 121)
>>> list(g)
[]
>>> #生成器对象已遍历结束,没有元素了
>>> g = ((i+2)*2 for i in range(10))
>>> g.__next__()
4
>>> next(g)
6

需要注意的是filter和map对象也具有类似的特点。
下面给出这次学习的相关例子:

#编写程序,生成包含20个各不相同的随机数列表
#然后将前10个元素按降序排列,后10个元素按升序排列
import random
aList=[random.randint(0,100) for i in range(20)]
print(aList)
font = sorted(aList[0:10],reverse = True)
print(font)
back = sorted(aList[10:20])
print(back)
font.extend(back)
print(font)
#编写程序,至少用两种方法计算100以内所有偶数的和
summ  = 0
print("The first way:")
for i in range(101):
    if i % 2 ==0:
        summ += i

print(summ)
print("The second way:")
a=[i for i in range(0,102,2)]
print(sum(a))
print(sum(range(0,101,2))
#编写程序用户输入一个三位医生的整数,输出其百位以上的数字
#例如,用户输入1234,程序输出12
x = input("清输入一个三位数以上的整数:")
answer = int(x[0:-2])
print(answer)
#编写程序,生成1000个0-1000之间的随机数
#并统计每个元素出现的次数
import random

aList = [random.randint(0,100) for i in range(1000)]

for a in aList:
    print(a,":",aList.count(a))


Python03-04Python03-04 小白和雨薇 发布了24 篇原创文章 · 获赞 12 · 访问量 544 私信 关注
上一篇:Python第二周学习


下一篇:排序-五种排序