为什么join()函数不会自动将其参数转换为字符串?你何时才不希望它们是字符串?

14

我们有一个列表:

myList = [1, "two"]

我想将它打印出来,通常我会使用类似这样的方法:

而想要打印出来,通常我会使用类似下面这样的方式:

"{0} and {1}".format(*myList)

但您也可以这样做:

" and ".join(myList)

但不幸的是:

>>> " and ".join(myList)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, int found

为什么它不会自动将接收到的列表转换为字符串?

在什么情况下您不需要将它们转换为字符串?我是否遗漏了某些微小的情况?


1
"import this": 明确胜于含蓄。 - falsetru
3个回答

14

来自Python之禅(Zen of Python):

明确胜于隐晦。

错误不应该悄悄地过去。

隐式地将数据转换为字符串容易隐藏bug,如果我突然有了本来应该是字符串的不同类型的变量,我真的想知道。如果你想显式地将其转换为字符串,你可以通过使用map()这个函数来实现:

''.join(map(str, myList))

1
很好的回答,但是“明确胜于隐晦”真的贯穿整个Python吗?例如,.sorted()默认为升序,第一个元素。 - LittleBobbyTables
1
@LittleBobbyTables:不,list.sort()默认使用比较。这取决于序列中的对象是什么意思。对于字符串、元组和列表,这是按字典顺序升序排列的。 - Martijn Pieters
1
@LittleBobbyTables: Python 2 中有很多错误,在 Python 3 中进行了纠正,例如 strunicode 之间的隐式转换,以及在对不同类型进行排序时无法真正进行默认排序。 - Martijn Pieters
1
@LittleBobbyTables:禅是一种哲学,是一个努力追求的北极星。是的,Python语言中有一些不太符合这个标准的地方,但str.join()确实遵循了这个标准。 - Martijn Pieters
我认为这是“显式优于隐式”+“特殊情况并不足以打破规则”的体现。在这个特定情况下,转换为str可能不是最糟糕的事情,但是尽量减少隐式强制转换的数量也是一个重要目标。(出于实用性考虑,你可以从我的冷死的手中夺走1 + 1.5,但我们不需要扩大这种情况。) - DSM
@DSM:实际上我也考虑过在这里引用 特殊情况,但我不想就 str.join() 不是特殊情况而争辩 - 当然它是 - 不,它不是等等。 - Martijn Pieters

3
试图按照原样执行类似于x = 4 + "8"的操作存在问题,因为其意义含混不清。应该让x包含"48"(将4隐式转换成str)还是12(将"8"隐式转换成int)?我们无法证明任何一种结果的正确性。
为避免这种混淆,Python要求明确转换其中一个操作数:
>>> x = str(4) + "8"
>>> y = 4 + int("8")
>>> print x
48
>>> print y
12

+1 是为了需要显式参数转换的实际理由。 - chepner
5
感谢您的回答,但这有点不相关,因为join()是关于指定用于连接列表项的字符串,这样就不会出现歧义。 - LittleBobbyTables
它仍然会在底层尝试 1 + " and " + "two",对吧?使用 mylist = [str(1), "two"] 可以使连接操作正常工作。 - Tetrinity
1
这对于 + 运算符是有意义的,但是 str.joinstr 类型的方法,显然不应该操作除字符串以外的任何东西。因此,如果您将所有内容都转换为字符串,就不会产生混淆。 - nog642

0

使用正确的类型是Python编程的一部分。像print这样的通用内置函数确实会进行转换(如果类支持__str__),这就是您应该进行转换的地方:

print来完成工作:

print(*myList, sep = " and ")

这是针对Python 3的,如果你还在使用Python 2,则使用以下代码:

from __future__ import print_function

Python不是强类型语言,它不像Java那样(谢天谢地!)。Join应该能够处理任何具有__str__方法的内容并使用它。这里没有歧义。 - OldGeeksGuide
Print是一个将内容打印到文件或iostream的函数,它不会生成字符串。如果我想使用str.join,我需要的是一个字符串。 - OldGeeksGuide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接