python3 - python数字列表转字符串




Python连接:为什么它是string.join(list)而不是list.join(string)? (6)

这一直困扰着我。 看起来这样会更好:

my_list = ["Hello", "world"]
print my_list.join("-")
# Produce: "Hello-world"

比这个:

my_list = ["Hello", "world"]
print "-".join(my_list)
# Produce: "Hello-world"

有没有特定的原因是这样的?


为什么它是string.join(list)而不是list.join(string)

这是因为join是一个“字符串”方法! 它从任何迭代中创建一个字符串。 如果我们将这种方法固定在列表上,那么当我们有不是列表的迭代器时呢?

如果你有一串字符串呢? 如果这是一个list方法,那么在将这些元素连接到单个字符串之前,您必须将每个这样的字符串迭代器都作为list进行投射! 例如:

some_strings = ('foo', 'bar', 'baz')

让我们滚动我们自己的列表连接方法:

class OurList(list): 
    def join(self, s):
        return s.join(self)

要使用它,请注意,我们必须首先从每个迭代中创建一个列表,以便在迭代中加入字符串,同时浪费内存和处理能力:

>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'

所以我们看到我们不得不添加一个额外的步骤来使用我们的list方法,而不是使用内建的字符串方法:

>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'

发电机性能警告

Python用来用str.join创建最终字符串的str.join实际上必须经过两次迭代,所以如果你提供了一个生成器表达式,它必须首先将它物化成一个列表,然后才能创建最终的字符串。

因此,在传递生成器时通常比列表str.join更好,但str.join是个例外:

>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173

尽管如此, str.join操作在语义上仍然是一个“字符串”操作,所以在str对象上使用str.join操作比在其他iterables上操作仍然有意义。


-声明你正在加入一个列表并转换成一个字符串。它是以结果为导向的(只是为了便于记忆和理解)

我制作了一个详尽的methods_of_string作为参考。

string_methonds_44 = {
    'convert': ['join','split', 'rsplit','splitlines', 'partition', 'rpartition'],
    'edit': ['replace', 'lstrip', 'rstrip', 'strip'],
    'search': ['endswith', 'startswith', 'count', 'index', 'find','rindex', 'rfind',],
    'condition': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric','isidentifier',
                  'islower','istitle', 'isupper','isprintable', 'isspace', ],
    'text': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
             'center', 'ljust', 'rjust', 'zfill', 'expandtabs','casefold'],
    'encode': ['translate', 'maketrans', 'encode'],
    'format': ['format', 'format_map']}

因为join()方法在字符串类中,而不是列表类?

我同意它看起来很有趣。

请参阅http://www.faqs.org/docs/diveintopython/odbchelper_join.html

历史笔记。 当我第一次学习Python时,我期望join是一个列表的方法,它将分隔符作为参数。 很多人都有同样的感受,并且在连接方法背后有一个故事。 在Python 1.6之前,字符串没有所有这些有用的方法。 有一个单独的字符串模块,其中包含所有的字符串函数; 每个函数都将一个字符串作为其第一个参数。 这些函数被认为足够重要,以便将它们放到字符串本身上,这对函数如lower,upper和split是有意义的。 但是许多硬核Python程序员反对新的连接方法,认为它应该是列表的方法,或者它不应该移动,而只是保留旧的字符串模块的一部分(仍然有很多其中有用的东西)。 我独占地使用了新的连接方法,但是你会看到以任何方式编写的代码,如果它真的困扰你,你可以使用旧的string.join函数。

--- Mark Pilgrim,潜入Python


我同意起初它是违反直觉的,但是有一个很好的理由。 加入不能成为列表的一种方法,因为:

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

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

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

如果连接是一个列表的方法,那么它必须检查它的参数来决定哪一个要调用。 而且你不能一起加入字节和字符串,所以他们拥有它的方式现在是合理的。


这在String方法中进行了讨论......最终在Python-Dev中进行了线程化,并被Guido接受。 该线程于1999年6月开始, str.join被包含在2000年9月发布的Python 1.6中(并支持Unicode)。 Python 2.0(支持的str方法,包括join )于2000年10月发布。

  • 本主题提出了四个选项:
    • str.join(seq)
    • seq.join(str)
    • seq.reduce(str)
    • 作为内置函数join
  • Guido不仅支持list s, tuple s,还支持所有序列/迭代。
  • seq.reduce(str)对于新来者来说很难。
  • seq.join(str)引入了序列对str / unicode的意外依赖。
  • join()作为内置函数只支持特定的数据类型。 所以使用内置的命名空间并不好。 如果join()支持多种数据类型,那么创建优化的实现将很困难,如果使用__add__方法实现,那么它是O(n²)。
  • 分隔符字符串( sep )不应省略。 显式比隐式更好。

在这个线程中没有其他的原因。

这里有一些额外的想法(我自己和我的朋友):

  • Unicode支持即将到来,但它不是最终的。 那时UTF-8是最有可能取代UCS2 / 4的。 要计算UTF-8字符串的总缓冲区长度,需要知道字符编码规则。
  • 那时,Python已经决定了一个通用的序列接口规则,用户可以创建一个类似序列(可迭代)的类。 但Python直到2.2时才支持扩展内置类型。 那时很难提供基本的迭代类(在另一个评论中提到)。

Guido的决定被记录在一个历史邮件中 ,决定str.join(seq)

很有趣,但确实看起来不错! 巴里,去吧...
--Guido van Rossum


这是因为任何迭代都可以被连接,而不仅仅是列表,但结果和“连接器”总是字符串。

例如:

import urllib2
print '\n############\n'.join(
    urllib2.urlopen('http://data.stackexchange.com/users/7095'))




join