这一直让我困惑。看起来这样会更好:

["Hello", "world"].join("-")

除此之外:

"-".join(["Hello", "world"])

有什么具体的原因吗?


当前回答

我同意一开始这是违反直觉的,但有一个很好的理由。联接不能是列表的方法,因为:

它也必须适用于不同的可迭代对象(元组、生成器等)它必须在不同类型的字符串之间具有不同的行为。

实际上有两种连接方法(Python 3.0):

>>> b"".join
<built-in method join of bytes object at 0x00A46800>
>>> "".join
<built-in method join of str object at 0x00A28D40>

如果join是列表的一个方法,那么它必须检查其参数,以决定调用其中的哪一个。而且你不能将byte和str连接在一起,所以它们现在的方式是有意义的。

其他回答

将其视为拆分的自然正交操作。

我明白为什么它适用于任何可迭代的东西,所以不能简单地在列表中实现。

为了可读性,我希望在语言中看到它,但我认为这实际上是不可行的-如果可迭代性是一个接口,那么它可以添加到接口中,但这只是一个约定,因此没有中心方法将它添加到可迭代的一组东西中。

我同意一开始这是违反直觉的,但有一个很好的理由。联接不能是列表的方法,因为:

它也必须适用于不同的可迭代对象(元组、生成器等)它必须在不同类型的字符串之间具有不同的行为。

实际上有两种连接方法(Python 3.0):

>>> b"".join
<built-in method join of bytes object at 0x00A46800>
>>> "".join
<built-in method join of str object at 0x00A28D40>

如果join是列表的一个方法,那么它必须检查其参数,以决定调用其中的哪一个。而且你不能将byte和str连接在一起,所以它们现在的方式是有意义的。

主要是因为someString.jjoin()的结果是字符串。

序列(列表或元组等)不会出现在结果中,只是一个字符串。因为结果是一个字符串,所以它作为字符串的方法是有意义的。

这是因为任何可迭代的都可以连接(例如,列表、元组、dict、集合),但其内容和“joiner”必须是字符串。

例如:

'_'.join(['welcome', 'to', 'stack', 'overflow'])
'_'.join(('welcome', 'to', 'stack', 'overflow'))
'welcome_to_stack_overflow'

使用字符串以外的其他内容将引发以下错误:

TypeError:序列项0:应为str实例,找到int

你不能只加入列表和元组。您可以加入几乎任何可迭代的。可迭代的包括生成器、映射、过滤器等

>>> '-'.join(chr(x) for x in range(48, 55))
'0-1-2-3-4-5-6'

>>> '-'.join(map(str, (1, 10, 100)))
'1-10-100'

使用生成器、地图、过滤器等的好处是它们几乎不需要内存,而且几乎是即时创建的。

这只是概念上的另一个原因:

str.join(<iterator>)

只有赋予str这种能力才有效。而不是向所有迭代器授予联接:列表、元组、集合、字典、生成器、映射、过滤器,所有这些迭代器都只有对象作为公共父对象。

当然,range()和zip()也是迭代器,但它们永远不会返回str,因此不能与str.jjoin()一起使用

>>> '-'.join(range(48, 55))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found