火柴人武林大会
156.74M · 2026-02-04
在Python中,字符串可以与数字相乘。
在Python中,字符串和数字之间不能使用加号( + ):
prefix = "year: "
year = 1999
prefix + year
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
prefix + year
~~~~~~~^~~~~~
TypeError: can only concatenate str (not "int") to str
您可以使用加号将两个数字相加:
year + 1
2000
或者将两个字符串连接起来:
prefix + str(year)
'year: 1999'
但它不适用于字符串和数字之间。
有趣的是,你可以将一个字符串乘以一个数字:
"ha" * 3
'hahaha'
你可以把这理解为自连接。我们将这个字符串与自身连接特定的次数:
"ha" + "ha" + "ha"
'hahaha'
字符串只能用整数自连接:
"ha" * 2.5
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
"ha" * 2.5
~~~~~^~~~~
TypeError: can't multiply sequence by non-int of type 'float'
字符串相乘非整数次是没有意义的。
有趣的是,负数*也可以*用于自连接,只是结果总是空字符串:
"ha" * -3
''
当你将一个字符串乘以0时,也会发生同样的情况:
"ha" * 0
''
任何支持字符串拼接的对象,很可能也支持自拼接。
因此,其他序列,如列表、元组和字节串,也可以进行自连接:
[2, 1, 3] * 2
[2, 1, 3, 2, 1, 3]
(4, 5) * 3
(4, 5, 4, 5, 4, 5)
b"text " * 3
b'text text text '
这算是一个挺有意思的功能,但它存在的意义是什么?它真的有用吗?
我偶尔会使用自连接来创建具有特定默认值的特定大小的列表。
例如,我们可以使用自连接来创建一个表示一年中 12 个月的列表,以统计该列表中某个事物出现的次数,并且我们希望将所有计数默认设置为零:
[0] * 12
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
但更多时候,我使用这个功能来创建一个由相同字符重复特定次数的字符串。
例如,我可能想在程序的输出部分之间打印 80 个连字符( - )。
print("-" * 80)
--------------------------------------------------------------------------------
就像在 Python 中创建新的数据结构或分配变量一样,自连接不会复制任何内容。
在Python中,给变量赋值并不会复制该值:
a = [2, 1, 3]
b = a
Python 中的变量类似于指针。因此,更改b指向的列表也会更改a指向的列表:
b.append(4)
b
[2, 1, 3, 4]
a
[2, 1, 3, 4]
这是因为这两个变量指向同一个对象。这就是Python中赋值操作的作用。
就像给变量赋值不会复制该值一样,使用列表或元组的自连接也不会复制这些项。
所以,如果我们尝试将一个包含列表的列表乘以3 ,从而将其自身连接三次:
rows = [[0, 0, 0]] * 3
最终我们会得到一个包含相同三项的列表:
rows
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
也就是说,索引0与索引1是同一个对象:
rows[0] is rows[1]
True
也就是说,如果我们修改其中一个内部列表,所有内部列表都会随之改变:
rows[1][1] = 7
rows
[[0, 7, 0], [0, 7, 0], [0, 7, 0]]
这是因为它们都属于同一个列表。
与大多数操作一样,自连接不会创建副本。
实际上,这意味着自连接通常只用于包含不可变项的序列,而不用于包含可变项的序列。
自连接可用于创建包含相同字符或相同字符序列且重复次数固定的字符串。它也适用于预先填充包含特定数量默认值的列表。
但是自连接不会复制任何内容,所以不要尝试用它来创建可变值的列表,例如列表的列表。
www.pythonmorsels.com/self-concat…
Python对象的自连接