21

Почему используется string.join(list), а не list.join(string)?

57

Вопрос о синтаксисе методов в JavaScript

Здравствуйте! У меня всегда была путаница с синтаксисом методов в JavaScript. Мне кажется, что следующий вариант был бы более логичным:

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

Чем этот:

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

Существует ли конкретная причина, почему метод join реализован именно таким образом? Буду признателен за разъяснения!

2 ответ(ов)

1

В строке "-".join(my_list) знак - указывает на то, что вы объединяете элементы списка в строку с помощью символа - в качестве разделителя. Это подчеркивает, что результатом операции является строка. (Это просто для легкого запоминания и понимания.)

Для вашего удобства я составил исчерпывающую таблицу методов работы со строками:

string_methods_44 = {
    'конвертация': ['join', 'split', 'rsplit', 'splitlines', 'partition', 'rpartition'],
    'редактирование': ['replace', 'lstrip', 'rstrip', 'strip'],
    'поиск': ['endswith', 'startswith', 'count', 'index', 'find', 'rindex', 'rfind'],
    'условие': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric', 'isidentifier',
                'islower', 'istitle', 'isupper', 'isprintable', 'isspace'],
    'текст': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
              'center', 'ljust', 'rjust', 'zfill', 'expandtabs', 'casefold'],
    'кодировка': ['translate', 'maketrans', 'encode'],
    'форматирование': ['format', 'format_map']
}

Эта таблица поможет вам быстро ориентироваться в доступных методах для работы со строками в Python.

0

Это происходит потому, что join является методом "строки"! Он создает строку из любого итерируемого объекта. Если бы мы добавили этот метод к спискам, что делать с итераторами, которые не являются списками?

Например, что если у вас есть кортеж строк? Если это был бы метод списка, вам пришлось бы сначала преобразовать каждый такой итератор строк в список, прежде чем вы смогли бы объединить элементы в одну строку! Вот пример:

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

Давайте создадим свой собственный метод объединения для списка:

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

И чтобы использовать его, обратите внимание, что сначала нужно создать список из каждого итератора, чтобы объединить строки в этом итераторе, что приводит к расходу памяти и вычислительных ресурсов:

>>> l = OurList(some_strings) # шаг 1, создаем наш список
>>> l.join(', ') # шаг 2, используем наш метод объединения!
'foo, bar, baz'

Таким образом, мы видим, что нам нужно добавить дополнительный шаг для использования нашего метода списка, вместо того чтобы просто воспользоваться встроенным методом строки:

>>> ' | '.join(some_strings) # один шаг!
'foo | bar | baz'

Ограничение производительности для генераторов

Алгоритм, используемый Python для создания финальной строки с помощью 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, а не у разнородных итерируемых объектов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь