Python网络爬虫:从入门到精通
上QQ阅读APP看书,第一时间看更新

1.3.1 “Hello,World!”与数据类型

输出一行“Hello, World!”,用C语言编写的程序语句是这样的:

#include <stdio.h>
int main()
{
  printf("Hello, World!");
  return 0;
}

而在Python中,可以用一行代码完成:

print('Hello, World!')

在Python中,每个变量都有一种数据类型,但和一些强类型语言不同,我们并不需要直接声明变量的数据类型。Python 会根据每个变量的初始赋值情况分析其类型,并在内部对其进行跟踪。Python内置的主要数据类型如下。

▪ Number,数值类型,可以是Integers(1和2,常缩写为int)、Float(1.1和1.2)、Fraction (1/2和2/3),或Complex Number(数学中的复数)。

▪ String,字符串,主要用于描述文本。

▪ List,列表,一种包含元素的序列。

▪ Tuple,元组,和列表类似,但它是不可变的。

▪ Set,一种包含元素的集合,其中的元素是无序的。

▪ Dict,字典,由键值对构成。

▪ Boolean,布尔类型,其值为True或False。

▪ Byte,字节,如一个以字节流表示的JPG文件。

从Number中的int开始,使用type关键字获取某个数据的类型。

print(type(1))    # <class 'int'>
a=1+2//3          # “//”表示整除
print(a)          # 1
print(type(a))    # <class 'int'>

提示

不同于C语言或者C++使用/*…*/和//的形式进行注释,在Python中注释通过“#”开头的字符串体现。注释内容不会被Python解释器作为程序语句。

对于int值和float值,Python中一般会使用小数点来区分。

a=9**9            # “**”表示幂次
print(a)          # 387420489
print(type(a))    # <class 'int'>
b=1.0
print(b)          # 1.0
print(type(b))    # <class 'float'>

这里需要注意的是,将一个int值与一个int值相加将得到一个int值。但将一个int值与一个 float值相加将得到一个float值。这是因为Python会在运算中把int值强制转换为float值,以进行加法运算。

c=a+b
print(c)
print(type(c))
# 387420490.0
# <class 'float'>

使用内置的关键字对变量进行int与float之间的强制转换是经常用到的。

int_num=100
float_num=100.1
print(float(int_num))
print(int(float_num))
# 100.0
# 100

在Python 2中曾有int和long(长整数类型)的区分,但在Python 3中,int吸收了Python 2.x中的int和long,不再对较大的整数和较小的整数做区分。

了解数值后,下面介绍数值运算。

a, b, c=1, 2, 3.0
# 一种赋值方法,此时a为1,b为2,c为3.0
print(a+b)   # 加法
print(a-b)   # 减法
print(a*c)    # 乘法
print(a/c)   # 除法
print(a//b)  # 整除
print(b**b)   # 幂运算
print(b%a)   # 求余
# 输出为:
# 3
# -1
# 3.0
# 0.3333333333333333
# 0
# 4
# 0

在Python中还可以表示相对比较特殊的分数和复数,分数可以通过fractions模块中的Fraction对象构造。

import fractions # 导入分数模块
a=fractions.Fraction(1,2)
b=fractions.Fraction(3,4)
print(a+b) # 5/4

复数可以用函数 complex(real, imag) 或者带有后缀j的浮点数来创建。

a=complex(1,2)
b=2+3j
print(type(a),type(b)) # <class 'complex'> <class 'complex'>
print(a+b) # (3+5j)
print(a*b) # (-4+7j)

布尔类型本身非常简单,Python中的布尔类型以True和False两个常量为值。

print(1<2) # True
print(1>2) # False

不过在Python中对布尔类型和if else条件语句判断的结合比较灵活,这些可以等到后面在实际编程中再详细探讨。

在介绍字符串之前,先对list(列表)和tuple(元组)做简单介绍。列表涉及Python中一个非常重要的概念:iterable(可迭代对象)。对于列表而言,序列中的每一个元素都在一个固定的位置(称之为索引)上,索引从“0”开始。列表中的元素可以是任何数据类型,在Python中列表对应的是方括号“[]”的表示形式。

l1=[1,2,3,4]
print(l1[0]) # 通过索引访问元素,输出:1
print(l1[1]) # 2
print(l1[-1])# 4
# 使用负值索引可从列表的尾部向前计数访问元素
# 任何非空列表的最后一个元素总是 list[-1]

列表切片(slice)可以简单地描述为从列表中取一部分的操作,通过指定两个索引,可以从列表中获取称作“切片”的某个部分。列表切片的返回值是一个新列表,从第一个索引开始,直到第二个索引结束(不包含第二个索引的元素),列表切片的使用非常灵活。

l1=[ i for i in range(20)] # 列表解析语句
# l1中的元素为0~20(不含20)的所有整数
print(l1)
print(l1[0:5]) # 取l1中的前5个元素
# [0, 1, 2, 3, 4]
print(l1[15:-1]) # 取索引为15的元素到最后一个元素(不含最后一个)
# [15, 16, 17, 18]
print(l1[:5]) #取前5个,“0”可省略
# 如果左切片索引为0,则可以将其留空而将“0”隐去。如果右切片索引为列表的长度,则也可以将其留空
# [0, 1, 2, 3, 4]
print(l1[1:]) #取除了索引为0(第一个)的元素之外的所有元素
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
l2=l1[:] # 取所有元素,其实是复制列表
print(l1[::2]) # 指定步数,取所有索引为偶数的元素
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print(l1[::-1]) # 倒着取所有元素
# [19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

向一个列表中添加新元素的方法也很多样。

l1=['a']
l1=l1+['b']
print(l1)
# ['a', 'b']
l1.append('c')
l1.insert(0,'x')
l1.insert(len(l1),'y')
print(l1)
# ['x', 'a', 'b', 'c', 'y']
l1.extend(['d','e'])
print(l1)
#['x', 'a', 'b', 'c', 'y', 'd', 'e']
l1.append(['f','g'])
print(l1)
# ['x', 'a', 'b', 'c', 'y', 'd', 'e', ['f', 'g']]

需要注意的是,extend()接收一个列表,并把其元素分别添加到原有的列表,类似于“扩展”。而append()是把参数(参数有可能也是一个列表)作为一个元素整体添加到原有的列表中。insert() 方法会将单个元素插入列表,其第一个参数表示列表中将插入的位置(索引)。

从列表中删除元素可使用的方法也不少。

# 从列表中删除
del l1[0]
print(l1)
# ['a', 'b', 'c', 'y', 'd', 'e', ['f', 'g']]
l1.remove('a') #remove()方法接收一个参数,并删除列表中第一次出现的该参数
print(l1)
# ['b', 'c', 'y', 'd', 'e', ['f', 'g']]
l1.pop() # 如果不带参数调用,则pop()方法将删除列表中最后的元素,并返回所删除元素的值
print(l1)
# ['b', 'c', 'y', 'd', 'e']
l1.pop(0) # 可以给pop()一个特定的索引
print(l1)
# ['c', 'y', 'd', 'e']

元组与列表非常相似,区别在于:元组是不可修改的,定义之后就“固定”了;元组在形式上是用“()”这样的圆括号标识的。由于元组是不可修改的,所以不能插入或删除元素。其操作与列表类似。

t1=(1,2,3,4,5)
print(t1[0]) # 1
print(t1[::-1]) # (5, 4, 3, 2, 1)
print(1 in t1) # 检查1是否在t1中,输出:True
print(t1.index(5)) #返回某个值对应的元素索引,输出:4

提示

元素可修改与不可修改是列表与元组的一大区别,基本上除了修改内部元素的操作,其他列表适用的操作都可以用于元组。

创建一个字符串时,将其用一对引号标识,引号可以是单引号(')或者双引号("),两者没有区别。字符串也是一个可迭代对象,因此,与取得列表中的元素一样,也可以通过索引取得字符串中的某个字符,一些适用于列表的操作同样适用于字符串。

str1='abcd'
print(str1[0]) # 索引访问
# a
print(str1[:2]) # 切片
# ab
str1=str1+'efg'
print(str1)
# abcdefg
str1=str1+'xyz'*2
print(str1) # abcdefgxyzxyz
# 格式化字符串
print('{} is a kind of {}.'.format('cat','mammal'))
# cat is a kind of mammal.
# 显示指定字段
print('{3} is in {2}, but {1} is in {0}'.format('China','Shanghai','US','New York'))
# New York is in US, but Shanghai is in China.
# 以一对三引号标识多行字符串
long_str='''I love this girl,
but I don't know if she likes me,
what I can do is to keep calm and stay alive.
'''
print(long_str)

集合的特点是无序且值唯一,创建集合和操作集合的常见方式包括。

set1={1,2,3}
l1=[4,5,6]
set2=set(l1)
print(set1) # {1,2,3}
print(set2) # {4,5,6}
# 添加元素
set1.add(10)
print(set1)
# {10, 1, 2, 3}
set1.add(2) # 无效语句,因为2在集合中已经存在
print(set1)
# {10, 1, 2, 3}
set1.update(set2) # 类似于列表的extend()操作
print(set1)
# {1, 2, 3, 4, 5, 6, 10}
# 删除元素
set1.discard(4)
print(set1)
# {1, 2, 3, 5, 6, 10}
set1.remove(5)
print(set1)
# {1, 2, 3, 6, 10}
set1.discard(20) # 无效语句,不会报错
# set1.remove(20) 使用remove()去除一个并不存在的值时会报错
set1.clear()
print(set1) # 清空集合
set1={1,2,3,4}
# 并集、交集与差集
print(set1.union(set2)) # 在set1或者set2中的元素
# {1, 2, 3, 4, 5, 6}
print(set1.intersection(set2)) # 同时在set1和set2中的元素
# {4}
print(set1.difference(set2)) # 在set1中但不在set2中的元素
# {1, 2, 3}
print(set1.symmetric_difference(set2)) # 只在set1或只在set2中的元素
# {1, 2, 3, 5, 6}

字典(dict)相对于列表、元组和集合会显得稍微复杂一点。Python中的字典是键值对(key-value)的无序集合。字典在形式上也和集合类似,创建字典和操作字典的基本方式如下。

d1={'a':1,'b':2} # 使用“{}”创建
d2=dict([['apple','fruit'],['lion','animal']]) # 使用dict关键字创建
d3=dict(name='Paris', status='alive', location='Ohio')
print(d1) # {'a': 1, 'b': 2}
print(d2) # {'apple': 'fruit', 'lion': 'animal'}
print(d3) # {'status': 'alive', 'location': 'Ohio', 'name': 'Paris'}
#访问元素
print(d1['a']) # 1
print(d3.get('name')) # Paris
# 使用get()方法获取不存在的键值对时不会触发异常
# 修改字典——添加或更新键值对
d1['c']=3
print(d1) # {'a': 1, 'b': 2, 'c': 3}
d1['c']=-3
print(d1) # {'c': -3, 'a': 1, 'b': 2}
d3.update(name='Jarvis',location='Virginia')
print(d3) # {'location': 'Virginia', 'name': 'Jarvis', 'status': 'alive'}
# 修改字典——删除键值对
del d1['b']
print(d1) # {'c': -3, 'a': 1}
d1.pop('c')
print(d1) # {'a': 1}
# 获取键或值
print(d3.keys()) # dict_keys(['status', 'name', 'location'])
print(d3.values()) # dict_values(['alive', 'Jarvis', 'Virginia'])
for k,v in d3.items():
print('{}:\t{}'.format(k,v))
# name:   Jarvis
# location:   Virginia
# status:  alive

Python中的列表、元组、集合和字典是最基本的几种数据类型,使用起来非常灵活,与Python的一些语法配合会使代码非常简洁、高效。掌握这些基本知识和操作是后续进行开发的基础。