CPython 的 str.join() 是不是有点低效?
Isn't CPython's str.join() a little inefficient?
This answer 及其注释提供了对 CPython 的内部工作原理的一些见解 str.join()
:
- 如果参数不是
list
或 tuple
,则会创建一个具有相同内容的新 list
。
- 参数被迭代一次,以计算它包含的字符串的长度。
- 已为新字符串分配内存。
- 最后,参数被第二次迭代,字符串被复制到内存中作为新字符串。
这对我来说似乎有问题。对于初学者,为什么要拒绝除两种之外的所有序列类型?将任何序列迭代两次而不是复制它会不会更快?为什么要创建 list
,特别是如果您不知道从中创建的可迭代对象的长度?您不需要随机访问,只需重复迭代,使用 list
意味着您可能必须在其生成期间多次重新分配和复制。使用链表或 deque
不是更有意义吗?
任何人都可以对这些设计决策提供一些见解吗?
For starters, why reject all sequence types but two? Wouldn't just iterating over any sequence twice instead of copying it be much faster?
join
的参数不必是序列。它可以是任何 iterable,并且一些 iterables 不能迭代多次。例如,它可以是一个生成器表达式,迭代一次后就会耗尽。
关于你的第二个问题,我不是很清楚,不过我猜想在内部使用列表和元组可以简化 C 级别的实现。我认为对你的问题更广泛的回答是,没有人真的打算对 str.join
进行所有可能的优化。我猜绝大多数用例都是在列表或元组上调用它。
This answer 及其注释提供了对 CPython 的内部工作原理的一些见解 str.join()
:
- 如果参数不是
list
或tuple
,则会创建一个具有相同内容的新list
。 - 参数被迭代一次,以计算它包含的字符串的长度。
- 已为新字符串分配内存。
- 最后,参数被第二次迭代,字符串被复制到内存中作为新字符串。
这对我来说似乎有问题。对于初学者,为什么要拒绝除两种之外的所有序列类型?将任何序列迭代两次而不是复制它会不会更快?为什么要创建 list
,特别是如果您不知道从中创建的可迭代对象的长度?您不需要随机访问,只需重复迭代,使用 list
意味着您可能必须在其生成期间多次重新分配和复制。使用链表或 deque
不是更有意义吗?
任何人都可以对这些设计决策提供一些见解吗?
For starters, why reject all sequence types but two? Wouldn't just iterating over any sequence twice instead of copying it be much faster?
join
的参数不必是序列。它可以是任何 iterable,并且一些 iterables 不能迭代多次。例如,它可以是一个生成器表达式,迭代一次后就会耗尽。
关于你的第二个问题,我不是很清楚,不过我猜想在内部使用列表和元组可以简化 C 级别的实现。我认为对你的问题更广泛的回答是,没有人真的打算对 str.join
进行所有可能的优化。我猜绝大多数用例都是在列表或元组上调用它。