字符串和列表看起来很像,但本质上不一样
本文最后更新于5 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

这个观察其实很重要:str 字符串和 list 列表,都支持索引,都能用下标去取某个位置的内容,看起来确实很像。
但是它们有一个非常关键的区别:

字符串是不可变类型(immutable),列表是可变类型(mutable)

这句话就是它们最核心的差别。

也就是说:

  • 字符串里的某个字符,可以取出来看
  • 但是不能直接改其中某一个位置
  • 列表里的某个元素,不但可以看,还可以直接改

所以你会感觉它们“表面像”,但真正写代码时,行为差很多。


先看它们相同的地方

1. 都可以用索引取值

name = "hello"
nums = [10, 20, 30]

print(name[0])
print(nums[0])

输出:

h
10

这里说明:

  • "hello" 的第 0 个位置是 "h"
  • [10, 20, 30] 的第 0 个位置是 10

也就是说,字符串和列表都属于“序列”,都可以按位置访问内容。


2. 都可以切片

name = "hello"
nums = [10, 20, 30, 40]

print(name[1:4])
print(nums[1:3])

输出:

ell
[20, 30]

说明:

  • 字符串切片,得到的还是字符串
  • 列表切片,得到的还是列表

3. 都可以用 for 循环遍历

name = "abc"
nums = [1, 2, 3]

for ch in name:
    print(ch)

for x in nums:
    print(x)

这也说明它们在“按顺序存放多个内容”这件事上很相似。


它们最关键的区别:能不能改

字符串不能这样改

name = "hello"
name[0] = "H"

这段代码会报错。

原因不是你索引写错了,而是:

字符串一旦创建好,里面的字符就不能原地修改。

你只能“重新生成一个新字符串”,不能直接把原来的某一个位置改掉。

比如想把 "hello" 变成 "Hello",要这样写:

name = "hello"
name = "H" + name[1:]
print(name)

输出:

Hello

这里不是“改原字符串里面的第 0 个字符”,而是:

  1. 取出 "H"
  2. 再取出原字符串后面的 "ello"
  3. 拼成一个新的字符串 "Hello"
  4. 再让变量 name 指向这个新字符串

列表可以直接改

nums = [10, 20, 30]
nums[0] = 99
print(nums)

输出:

[99, 20, 30]

这说明列表里面的元素,是可以直接修改的。

所以你可以把列表理解成:

一个可以随时增删改的“可变容器”


用最直白的话区分一下

你可以先这样记:

  • 字符串:更像“一整段文字”,通常用来表示文本内容
  • 列表:更像“一个盒子,里面放很多东西”,通常用来存多个数据

虽然字符串看起来也像“装了很多字符”,但 Python 把它当作“文本”来处理,所以它不允许你随便改某个字符。
而列表本来就是为了存多个元素并方便修改而设计的,所以它能改。


它们合并的时候也有相似点,但结果不同

字符串合并

a = "hello"
b = "world"
print(a + b)

输出:

helloworld

如果想中间有空格:

print(a + " " + b)

输出:

hello world

这里的 +字符串拼接


列表合并

a = [1, 2]
b = [3, 4]
print(a + b)

输出:

[1, 2, 3, 4]

这里的 +把两个列表连接起来,得到一个新的列表。

所以虽然都能用 +,但是含义要分清:

  • 字符串的 +:拼文本
  • 列表的 +:拼元素序列

print 直接打印时,该怎么操作

这个部分很基础,但非常重要。

1. 直接打印字符串

name = "hello"
print(name)

输出:

hello

字符串直接打印,就是把文字显示出来。


2. 直接打印列表

nums = [10, 20, 30]
print(nums)

输出:

[10, 20, 30]

这里你会发现,列表打印出来会带中括号,因为 Python 在告诉你:这是一个列表。


如果我不想让列表带中括号打印,怎么办

这是初学者很容易碰到的问题。

比如:

words = ["a", "b", "c"]
print(words)

输出是:

['a', 'b', 'c']

如果你想打印成:

a b c

可以用下面的方法。

方法1:用 for 循环逐个打印

words = ["a", "b", "c"]

for w in words:
    print(w)

输出:

a
b
c

这是“一行一个”。


方法2:用 join() 把字符串列表拼起来

words = ["a", "b", "c"]
print(" ".join(words))

输出:

a b c

这里要注意:

join() 只能拼接“字符串列表”。

也就是说,下面这种可以:

words = ["hello", "python", "world"]
print("-".join(words))

输出:

hello-python-world

如果列表里是数字,不能直接 join

比如:

nums = [1, 2, 3]
print(" ".join(nums))

这会报错。

因为 join() 要求列表里的每个元素都必须是字符串,但这里是整数。

要先转成字符串:

nums = [1, 2, 3]

for n in nums:
    print(n)

或者以后学得再多一点时,再用更方便的转换方法。

对于初学阶段,你先记住:

  • 列表里如果是数字,最稳妥的方法是 for 循环打印
  • 列表里如果本来就是字符串,可以用 join()

从思路到代码:怎么判断该用字符串还是列表

写代码时,可以先问自己一句话:

我现在处理的是“一段文字”,还是“多个独立的数据项”?

如果是一段文字,用字符串

例如:

  • 姓名
  • 一句话
  • 一个单词
  • 用户输入的一行文本
name = "Tom"
sentence = "I like Python"

如果是多个独立数据,用列表

例如:

  • 多个成绩
  • 多个名字
  • 多个商品
  • 多个数字
scores = [90, 85, 100]
names = ["Tom", "Jack", "Lucy"]

一个非常典型的对比例子

字符串

text = "abc"
print(text[1])

输出:

b

这里取出来的是一个字符。

但是不能改:

text[1] = "x"

不行。


列表

letters = ["a", "b", "c"]
print(letters[1])

输出:

b

而且可以改:

letters[1] = "x"
print(letters)

输出:

['a', 'x', 'c']

所以你可以看到:

  • 字符串像“不能拆开改的文本”
  • 列表像“可以拆开改的元素集合”

再补一个容易混淆的点:字符串中的每个字符也是字符串

这个地方初学者很容易忽略。

text = "hello"
print(text[0])
print(type(text[0]))

输出:

h
<class 'str'>

也就是说:

text[0] 取出来的不是“字符类型”,而是一个长度为 1 的字符串。

Python 里没有单独的“字符类型”,单个字符本质上还是字符串。


常见错误与易混点

1. 以为字符串既然能索引,就一定能修改

这是最常见误区。

能索引,只说明你能“访问它的某个位置”,不代表你能改。


2. 把列表和字符串的打印效果混为一谈

print("hello")
print(["h", "e", "l", "l", "o"])

输出完全不一样:

hello
['h', 'e', 'l', 'l', 'o']

因为一个是字符串,一个是列表。


3. 对数字列表直接使用 join()

nums = [1, 2, 3]
print(" ".join(nums))

这是错误的。

因为 join() 只能连接字符串。


4. 误以为字符串加法和列表加法是同一种意思

虽然都写 +,但本质不一样:

  • "ab" + "cd" 得到 "abcd"
  • [1, 2] + [3, 4] 得到 [1, 2, 3, 4]

形式一样,操作对象不同,结果也不同。


本节小结

你可以先把核心区别记成下面这几句话:

对比点字符串 str列表 list
是否支持索引支持支持
是否支持切片支持支持
是否能遍历
是否能直接修改某个位置不能
主要用途表示文本存放多个元素
直接 print() 的效果直接显示文本显示整个列表结构

最重要的一句是:

字符串是不可变的,列表是可变的。


最小可运行例子

你可以直接运行下面这段,感受一下区别:

text = "hello"
nums = [1, 2, 3]

print("字符串第0个元素:", text[0])
print("列表第0个元素:", nums[0])

nums[0] = 100
print("修改后的列表:", nums)

print("直接打印字符串:", text)
print("直接打印列表:", nums)

输出大概是:

字符串第0个元素: h
列表第0个元素: 1
修改后的列表: [100, 2, 3]
直接打印字符串: hello
直接打印列表: [100, 2, 3]

练习

题目

写一段程序,完成下面几件事:

  1. 定义一个字符串 "python"
  2. 打印它的第 2 个字符
  3. 定义一个列表 [10, 20, 30]
  4. 把列表中第 2 个元素改成 99
  5. 打印修改后的列表

提示

  • 索引从 0 开始
  • 第 2 个字符,其实索引是 1
  • 列表可以直接写 列表名[索引] = 新值

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇