输入与输出
导读
大家好,很高兴又和大家见面啦!!!
在上一篇内容中我们介绍了Python中的数据类型。经过上一篇的介绍,我们不难发现Python与C/C++还是有所不同的,不管是变量的数据类型也好,还是数据类型的种类也好,又或者是类型之间的转化也好,都是存在着一定的差异:
- 变量的数据类型之间的差异:
- C/C++中的变量的数据类型为静态数据类型
- Python中的变量的数据类型为动态数据类型
- 数据类型种类之间的差异:
- C语言中共有6大数据类型:
- 整型——字符型(
char
)、短整型(short
)、整型(int
)、长整型(long
)、更长的整型(long long
) - 浮点型——单精度浮点型(
float
)、双精度浮点型(double
) - 布尔型——真(
true
)和假(false
) - 指针型——整型指针型、浮点型指针型、数组指针型、指针指针型(多级指针)、结构体指针型
- 数组型——整型数组型、浮点型数组型、指针数组型、结构体数组型、数组数组型(多维数组)
- 自定义类型——结构体类型、枚举类型、联合体类型
- 在Python中共有7大数据类型:
- 数字(
Number
)——整型(int
)、浮点型(float
)、复数(complex
) - 字符串(
String
)——由单引号''
或者双引号""
表示 - 布尔(
Bool
)——整型(int
)的子类型 - 列表(
List
) - 元组(
Tuple
) - 字典(
Dictionary
) - 集合(
Set
)
- 数据类型之间的转换的差异:
- C语言中的数据类型转换:
- 隐式类型转换:
char/short/int
之间的运算会通过整型提升与截断的方式完成运算:int/float/long/double/long long/long double
之间的运算会通过算术转换的方式完成运算——低等级的数据类型会无条件转换成高等级的数据类型;
- 显示类型转换:
- 通过强制类型转换操作符
()
完成转换
- Python中的数据类型转换:
- 隐式类型转换:
bool < int < float < complex
之间的运算,较小的数据类型会无条件转换成较大的数据类型;
- 显式类型转换:
- 通过类型转换内置函数完成转换
对于不同的计算机语言,输入与输出都是至关重要的一个内容,它代表着使用者与计算机之间的交互方式。不同的语言对于输入输出的方式都有着不同的探索:
- C语言中的输入与输出:
- 通过
scanf()
、getc()
、gets()
、fscanf()
……等库函数实现输入; - 通过
printf()
、putc()
、puts
、fprintf()
……等库函数实现输出;
- C++中的输入与输出:
- 通过
cin
、wcin
与流提取>>
操作符实现输入 - 通过
cout
、wcout
与流插入<<
操作符实现输出
那对于Python而言,它又会有什么样的输入输出方式呢?在今天的内容中我们将会对其输入与输出进行探讨。
一、Python中的输出
在数据结构中我们有学习过,对于一个算法而言,可以有0个输入,至少有1个输出,因此,输出对于一门计算机语言来说,是至关重要的存在。
1.1 基本用法
在前面的介绍中,我们已经开始接触了Python中的输出方式——通过print()
函数实现输出:
在Python中,print
函数可以直接用于输出字符串、变量的值以及表达式的值,并且在输出时,函数会自动输出一个换行,如果我们希望将结果输出在同一行,那就需要给函数传入第二个参数——end,如下所示:
这种换行输出与不换行输出就是print函数的一个最基础的用法。在Python中,我们同样可以像C/C++一样实现格式化的输入与输出;
1.2 格式化输出
Python最早支持格式化打印时是效仿的C语言通过printf
来实现。但是printf
实现时会存在一个问题,当我们在打印的过程中使用了错误的占位符,就容易导致结果出现错误,因此在Python 3.6版本中对此进行了改进,开始支持f-string
的格式化打印方式:
格式化输出的一个基本用法就是通过在字符串前面加上一个f,字符串中通过花括号{}来格式化输出字符串与花括号中的值:
- f表示的是format——格式化
- {}表示的是需要输出对象的值——可以是具体的对象、表达式、函数……
这种输出方式的优势在于我们不需要对输出的值的具体类型进行判断了,也就不需要再使用占位符进行输出。
1.3 通过:
格式化值的输出
在Python中,如果我们想实现对值的输出进行格式化,如输出小数时指定输出小数位数、输出整数时指定输出整数宽度,这时我们就可以通过冒号:
来进行进一步的格式化输出,如下所示:
在Python中对于整数宽度的格式化输出我们不难发现,它并不是像C语言中的通过宽度值的正负来进行不同方向的宽度输出,而是统一的进行右对齐,宽度值的绝对值为输出整数的最小宽度。
那如果我想要指定对齐的方向应该如何操作呢?这里就需要用到对齐符号:
- 左对齐——
<
- 右对齐——
>
- 居中对齐——
^
如下所示:
这时有朋友可能就有疑问了,这个整型确实根据不同的对齐符号进行了不同方向的对齐,为什么小数没有变化呢?这是不是说明这些对齐符号对小数的输出不起作用呢?
实际上并不是这样,我们只需要给小数的整数部分加上宽度,即可看到对应的对齐,如下所示:
可以看到,当给输出值指定宽度后,小数也会根据不同的对齐符号来进行对齐。为什么会这样呢?
这就涉及到值的宽度和精度的问题了:
- 宽度——输出值的最小字符,如宽度为10,输出时最少输出10个字符,这时就会有2种情况:
- 输出的值的字符数量<10:不足十个字符的部分用空格填补;
- 输出的值的字符数量>=10:正常输出对应的值
- 精度——输出值的小数位数,如精度为3,输出时保留3位小数,这时同样有两种情况:
- 输出的值的小数位数<3:不足的位数用0填补;
- 输出的值的小数位数>=3:超出的部分按四舍五入的方式保留小数;
实际上所谓的对齐是根据值的输出宽度所决定的,我们对小数保留不同的位数这只是值的输出精度:
- 当只指定精度不指定宽度时,默认宽度为输出值的实际宽度,因此我们会看到输出的数值都是左对齐的形式
- 当只指定宽度不指定精度时,默认的精度为6,我们会看到小数点后的六位小数;
1.4 其它格式化输出
除了上述的这些格式化输出的用法外,我们通过:
还能实现按不同进制输出、输出正负号、以百分比的格式输出、以逗号分隔的数字形式输出、以指数计数法的形式输出等格式化输出,如下所示:
这里需要注意的是保留符号输出与输出正负值的区别:
- 保留符号输出——在冒号右侧添正负号:
- 值为正:添正号则保留正号输出;添负号则直接输出原值
- 值为负:添正号则直接输出原值;添负号则保留负号输出
- 正负值输出——在冒号左侧添正负号:
- 添正号则正常输出
- 添负号则输出相反数
输出的内容我们就先介绍到这里,大家如果感兴趣的话可以复制这些测试代码自己下去测试一下:
# print(f{:})——格式化输出值
print("Python 中的格式化输出值")
a = 3.1415926
print(f"{a:.0f}") # 保留0为小数——按四舍五入
print(f"{a:.3f}") # 保留3位小数
print(f"{a:10f}") # 宽度为10
print(f"{a:<10.3f}") # 左对齐,保留3位小数
print(f"{a:>10.3f}") # 右对齐,保留3位小数
print(f"{a:^10.3f}") # 居中对齐,保留3位小数
a = 5
print(f"{a:10d}") # 宽度为10
print(f"{a:-10d}") # 宽度为10
print(f"{a:<10d}") # 左对齐,宽度为10
print(f"{a:>10d}") # 右对齐,宽度为10
print(f"{a:^10d}") # 居中对齐,宽度为10
print("\n")
# print(f{:})——格式化输出值的其它格式化输出
a = -1.5263478
print(f"{a:+.0f}") # 保留正号输出,不保留小数
print(f"{a:-.0f}") # 保留符号输出,不保留小数
print(f"{+a:.0f}") # 输出正值,不保留小数
print(f"{-a:.0f}\n") # 输出负值,不保留小数
a = 1.5263478
print(f"{a:+.0f}") # 保留正号输出,不保留小数
print(f"{a:-.0f}") # 保留负号输出,不保留小数
print(f"{+a:.0f}") # 输出正值,不保留小数
print(f"{-a:.0f}") # 输出负值,不保留小数
print(f"{a:.2%}\n") # 以百分号的形式输出,保留2位小数
a = 1000000
print(f"{a:,}") # 以逗号分隔的形式输出
print(f"{a:.2e}") # 以指数计数法的形式输出
print(f"{a:b}") # 以二进制的形式输出
print(f"{a:o}") # 以八进制的形式输出
print(f"{a:d}") # 以十进制的形式输出
print(f"{a:x}") # 以十六进制的形式输出
二、Python中的输入
Python中的输入与输出一样,同样借助于内建函数。
Python中执行输入的内建函数为input()
——标准输入函数,返回一个字符串。
这时有朋友可能就会有疑问了,如果只是通过这个内建函数来执行输入,那我们如何来输入数字呢?
现在有朋友可能已经反应过来了——通过int()
来对字符串进行类型转换。
没错,在Python中,我们通过input()
这个输入函数获取到的就是我们输入的一行字符串,为了能够让我们输入的内容变成我们需要的数据,这时就需要通过一系列的对字符串进行操作的内置函数来完成。具体的内容在后面的篇章中会进行详细介绍,这里我们就介绍一下如果通过input函数获取单个数据和多个数据。
2.1 基本用法
input()
作为Python中的输入函数它仅有一个参数,也可以没有参数。其参数的内容为一个字符串,字符串中的内容会直接输出到控制台上,如下所示:
可以看到,我们输入的内容为绿色的内容,程序输出的内容为白色的内容。
这里有一点需要说明一下,可能有朋友第一次使用这个函数是比较疑惑,在程序运行后输入的内容会出现在代码行,而不是在控制台,这个问题应该怎么解决呢?
很简单我们只需要将鼠标移动到控制台窗口,在想要执行输入的位置点击一下即可,如下所示:
我们可以看到此时运行程序时,光标是停留在代码行,并在不停的闪烁,这时我们只需要将光标移动到下方的控制台窗口即可,如下所示:
可以看到,当我们使用鼠标在下方控制台窗口中点击一下后,光标就会移动到控制台中,这时我们就可以执行输入了,如下所示:
当我们执行输入后,光标会自动移动到执行输入的那一行。当然为了看的更清楚一点,我们可以在函数中传入一个字符串来作为输入的提示信息,如下所示:
可以看到,虽然此时光标还是停留在代码行,但是控制台窗口中已经将提示信息给打印了出来,这样我们就能更直观的知道我们应该在哪一行进行输入。
以上就是input
函数的一个基本用法,通过这个基本用法我们就可以获取到输入的字符串,但是我们应该如何获取多个数据呢?难道是通过多个input吗?
接下来我们就来简单介绍一下如何通过一个input
函数获取多个数据。
2.2 split()
方法
在Python的字符串中存在一系列的内建函数,这些函数只能够对字符串起作用,因此我们称这一类函数为方法。
在字符串的各种方法中有一种方法可以将字符串分割成多个小字符串,并返回一个列表,这个方法就是我们现在要介绍的split()
。
简单的理解就是该函数有两个参数:
- 参数1:用来分割字符串的分隔符
- 参数2:分割字符串的分隔次数
这两个参数都是有一个默认值,当我们不对其进行传参时,split默认以所有的空字符为分隔符对整个字符串中存在空字符的位置进行分割,并将分割后的所有字符串存放入一个列表中进行返回,如下所示:
可以看到,此时我们就获得了多个数字字符串,当我们需要获取这些数字时,我们就可以通过循环以及类型转换的相关函数对所有的字符串执行类型转换即可,如下所示:
可以看到,此时我们就将列表a中的所有字符串转换成了整数。当然我们也可以传入固定的分隔符和分割次数来进行字符串分割,如下所示:
可以看到,此时我们以空格作为分隔符,让函数将字符串分割两次时,函数会根据空格的位置依次进行分割,因此我们可以看到当输入的内容中存在多个空格时,则会出现一些空字符串。
那有没有办法在进行分割时直接去掉这些空格字符串呢?这里就需要我们直接通过split来执行分割,如下所示:
可以看到,此时我指定的参数是分割次数,函数需要对字符串分割两次,此时无论输入的字符串中间有多少空格,被分割的对象左右的空格都会被作为分隔符。
因此我们可以看到函数首先自动去掉了首字符左侧的空字符,以右侧的空字符为分割点进行第一次分割,以第二个单词右侧的空字符为第二个分割点进行第二次分割,而第三个单词开始的内容则被作为一整个字符串存入列表中。
从这次测试我们可以得到一个结论:
- 当我们想要去掉多个单词中间的多个空格时,可以通过
split()
直接对整个字符串进行分割
2.3 split()习题演练
151. 反转字符串中的单词——双指针、字符串——中等
这一题在力扣中难度为中等,如果通过C语言来解题的话则有三种解题思路:
- 思路1:借助额外的空间来以单词为单位逆序存储源空间中的字符串
- 思路2:先反转整个字符串,后反转字符串中的每一个单词
- 思路3:将字符串分割成一个一个的单词,再以单词为一个元素进行反转,最后通过空格拼接所有单词
思路1和思路2是通过双指针来进行求解,而思路3则是通过字符串中的不同的库函数来进行求解,三种思路都是可行的,有兴趣的朋友可以通过C语言来尝试一下。
下面我们如果通过Python来解题的话,我们可以直接采用思路3的方式来完成求解:
- 通过
input()
获取输入的字符串并通过split()
对字符串进行分割获取由单词组成的字符串列表 - 通过
revers()
方法完成列表中的元素反转 - 通过
join()
方法指定' '
作为分隔符来连接字符串列表中的所有元素
对应代码如下所示:
s = input().split() # 1.通过input获取字符串并通过split分割字符串
s.reverse() # 通过reverse()方法反转列表中的元素
s = ' '.join(s) # 通过join()方法指定空格为分隔符连接列表中的元素
print(s)
测试结果如下所示:
如果是写成函数的话,则不再需要通过input()
来获取字符串,可以直接通过split()
将传入的参数进行反转,并直接返回完成连接的字符串,如下所示:
下面我给大家看一下通过C语言要实现这一题的相关代码:
思路1:双指针——通过额外的空间求解
char* reverseWords(char* s) {
//去收尾空格
int len = strlen(s);
int l = 0, r = len - 1;
while (s[l] == ' ') {
for (int i = l; s[i]; i++) {
s[i] = s[i + 1];
}
len--;
r--;
}
while (s[r] == ' ') {
len--;
r--;
}
//申请新空间
char* str = (char*)calloc(len + 1, sizeof(char));
assert(str);
//逆序拷贝单词
l = r;
int i = 0; //新字符串下标
r++;
while (l >= 0) {
if (s[l] == ' ') {
int flag = 0;
for (int j = l + 1; j < r; j++) {
str[i++] = s[j];
flag = 1;
}
if (flag)
str[i++] = ' ';
r = l;
}
l--;
}
for (int j = 0; j < r; j++) {
str[i++] = s[j];
}
return str;
}
思路2:双指针——反转源字符串再反转每一个单词
void move(char* s,int l) {
for (int i = l; s[i]; i++) {
s[i] = s[i + 1];
}
}
void swap(char* l, char* r) {
char tmp = *l;
*l = *r;
*r = tmp;
}
char* reverseWords(char* s) {
//去收尾空格
int len = strlen(s);
int l = 0, r = len - 1;
while (s[l] == ' ') {
move(s, l);
len--;
r--;
}
while (s[r] == ' ') {
s[r] = '\0';
len--;
r--;
}
//反转整个字符串
while (l < r) {
swap(&s[l], &s[r]);
l++, r--;
}
//反转单词
l = 0, r = 1;
while (r < len) {
//获取完整单词长度
while (s[r] && s[r] != ' ')
r++;
//处理最后一个单词
r--;
//记录单词长度
int end = r + 1;
//翻转单词
while (l < r) {
swap(&s[l], &s[r]);
l++, r--;
}
//记录下一个单词首字母位置
l = end + 1;
//去掉单词间的空格
while (l <= len && s[l] == ' ') {
move(s, l);
len--;
}
r = l;
}
return s;
}
思路三:字符串——通过字符串中的库函数求解
void Swap(char** ch1, char** ch2) {
char* tmp = *ch1;
*ch1 = *ch2;
*ch2 = tmp;
}
char* reverseMessage(char* message) {
int len = strlen(message);
char* str[10000] = { 0 };
int i = 0;
//分割字符串
for (str[i] = strtok(message, " "); str[i]; str[i] = strtok(NULL, " ")) {
i++;
}
//删除空格
for (int j = 0; j < i; j++) {
if (!str[j])
str[j] = str[j + 1];
}
if (str[0] == NULL)
return "";
//反转单词
int l = 0, r = i - 1;
while (l < r) {
Swap(&str[l], &str[r]);
l++, r--;
}
char* ans = (char*)calloc(len + 1, 1);
if (!ans)
return NULL;
strcat(ans, str[0]);
//连接字符串
for (int j = 1; j < i; j++) {
strcat(ans, " ");
strcat(ans, str[j]);
}
return ans;
}
从这里可以看到,Python这门语言确实够简洁的,我们想要实现的功能就3点,转换成对应的代码也就3条语句。
希望通过这道力扣网的练习题,大家能够理解split()
方法的用法。对于字符串中的其它方法以及列表的方法,在后续的内容中会进一步介绍这里就不在继续展开了。