Комментарии 24
В качестве предложения. Было бы замечательно сопровождать рассказ об операциях с коллекциями информацией о сложности операций в О-нотации. Это полезная информация при выборе коллекций для использования.
0
В конце первой статьи приведены ссылки на информацию по алгоритмической сложности операций с коллекциями.
0
a.append(b)
print(a, b) # [1, 2, 3, [4, 5]] [4, 5]
Это — не конкатенация, уберите.
Чтоб два раза не вставать:
>>> a, b = [1, 2, 3], [4, 5]
>>> a + b # вот это - конкатенация
[1, 2, 3, 4, 5]
>>> [*a, *b] # работает на версии питона 3.5 и выше
[1, 2, 3, 4, 5]
>>>
и, наконец,
>>> a += b # эквивалентно a.extend(b)
>>> a
[1, 2, 3, 4, 5]
+1
Большое спасибо за Ваши дельные замечания и дополнения!
Убрал термин конкатенация везде, поставил вместо него объединение, так как четкого однозначного определения не нашел, а суть указанных мной способов — объединение коллекций или добавление в нее нового элемента.
Добавил комментарии
Убрал термин конкатенация везде, поставил вместо него объединение, так как четкого однозначного определения не нашел, а суть указанных мной способов — объединение коллекций или добавление в нее нового элемента.
[*a, *b] - добавил этот способ с указанием Вашего авторства
Добавил комментарии
a += b # эквивалентно a.extend(b)
a += [b] # эквивалентно a.append(b)
0
a = set(['a', 'b'])
— этот синтаксис устарел лет десять назад, с появлением литерала множества:
a = {'a', 'b'}
+1
Я бы ещё добавил, что все приведённые варианты копирования списков «наивные»:
Визуализатор 1;
Если нужно копировать рекурсивно по полной:
Причём копирует всё достаточно аккуратно:
(аккуратно, но абсолютно всё. Функции и всё, что в них замкнуто, скажем, просто дублируются)
Визуализатор 2.
>>> a = [1, [2, 3], 4]
# В списке ссылка на объект 1, на объект (список), на объект 4
>>> b = a.copy()
# Новый объект список, в котором ровно те же ссылки, в частности ссылка на тот же список
>>> a[1].append(3.5)
# Так как ссылка на список общая, то и список общий
>>> print(b)
[1, [2, 3, 3.5], 4]
Визуализатор 1;
Если нужно копировать рекурсивно по полной:
>>> from copy import deepcopy
>>> c = deepcopy(a)
>>> a[1].append(3.75)
>>> print(c)
[1, [2, 3, 3.5], 4]
>>> print(a)
[1, [2, 3, 3.5, 3.75], 4]
Причём копирует всё достаточно аккуратно:
from copy import deepcopy
a = [1, 2]
b = [3, [[5, [a, 4], a], a, 6], a]
c = deepcopy(b)
a[1] = 9
print(b)
print(c)
c[2][1] = 3
print(c)
print(id(c[2]), id(c[1][1]), id(c[1][0][2]), id(c[1][0][1][0]))
[3, [[5, [[1, 9], 4], [1, 9]], [1, 9], 6], [1, 9]]
[3, [[5, [[1, 2], 4], [1, 2]], [1, 2], 6], [1, 2]]
[3, [[5, [[1, 3], 4], [1, 3]], [1, 3], 6], [1, 3]]
15864976 15864976 15864976 15864976
(аккуратно, но абсолютно всё. Функции и всё, что в них замкнуто, скажем, просто дублируются)
Визуализатор 2.
+1
Для операций над множествами intersection и symmetric_difference имеется короткая форма записи:
a = {'a', 'b'}
b = { 'b', 'c'}
c = a & b # c = a.intersection(b)
print(c) # {'b'}
c = a ^ b # c = a.symmetric_difference(b)
print(c) # {'c', 'a'}
+2
В Питоне 3.5 появился новый более изящный способ
На самом деле ещё во втором питоне можно было получать третий словарь путём слияния двух других:
dict3 = dict(dict1, **dict2)
+1
> В Питоне 3.5 появился новый более изящный способ
чем это они изящный? Вот если бы + перегрузили это было бы изящно
чем это они изящный? Вот если бы + перегрузили это было бы изящно
0
Перегрузить + конечно было бы еще изящней, но это явно четче и понятней, чем комбинация .copy() и .update()
Собственно способ указанный renskiy выше тоже очень хорош, добавлю его чуть позже в статью.
Собственно способ указанный renskiy выше тоже очень хорош, добавлю его чуть позже в статью.
0
Перегружать немного опасно, так как операция слияния словарей разрушительна.
Что должна делать
{1: 'one'} + {1: 'zero'}
?
Всевозможные варианты вида dict(dict1, **dict2) и dict(**dict1, **dict2) вернут {1: 'zero'}.
Что должна делать
{1: 'one'} + {1: 'zero'}
?
Всевозможные варианты вида dict(dict1, **dict2) и dict(**dict1, **dict2) вернут {1: 'zero'}.
+1
Операцию + над словарями можно заменить такой штукой.
>>> x = {"a": 1}
>>> y = {"b": 2}
>>> dict(x.items(), **y)
{'a': 1, 'b': 2}
0
Ну и + должен делать также, только при этом быть значительно читаемее
0
согласен, значит не сложение, а какой-нибудь метод я-ля union или merge, но без магических символов в стиле си, не так
а так
dict3 = dict(dict1, **dict2)
а так
dict3 = merge(dict1, dict2)
0
В целом, такая функция в 5 строк пишется. Но, как-то, это unpythonic, нет единственного способа сделать это правильно.
0
Вот по поводу магических символов согласился бы в том случае, если бы это было введено специально для объединения словарей, но это стандартный синтаксис передачи переменного числа параметров в функцию. Это гибкий и удобный способ, вполне в духе Питона.
Почему это не должно работать в функции создания словаря dict() — это ведь по сути такая же функция как и остальные?
Более того, при создании словаря не функцией dict(), а задав пары ключ: значение в фигурных скобках {} мы по сути имеем дело с коротким синтаксисом вызова той самой функции, так что вполне логично применять синтаксис по передаче переменного числа аргументов и тут.
Почему это не должно работать в функции создания словаря dict() — это ведь по сути такая же функция как и остальные?
Более того, при создании словаря не функцией dict(), а задав пары ключ: значение в фигурных скобках {} мы по сути имеем дело с коротким синтаксисом вызова той самой функции, так что вполне логично применять синтаксис по передаче переменного числа аргументов и тут.
0
Кстати, важный момент это мерджинг вложенных словарей, то что в перле выглядит как merge($hash1, %hash2) в питоне какими-то замороченными способами делается
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Python: коллекции, часть 3/4: объединение коллекций, добавление и удаление элементов