- PVSM.RU - https://www.pvsm.ru -
Продолжим изучать общие принципы работы со стандартными коллекциями (модуль collections в ней не рассматривается) Python. Будут рассматриваться способы объединения и обновления коллекций с формированием новой или изменением исходной, а также способы добавлять и удалять элементы в изменяемые коллекции.
Данная статья является продолжением моей статьи "Python: коллекции, часть 2: индексирование, срезы, сортировка [1]".
Для кого: для изучающих Python и уже имеющих начальное представление о коллекциях и работе с ними, желающих систематизировать и углубить свои знания, сложить их в целостную картину.
Рассмотрим способы объединения строк, кортежей, списков, словарей без изменения исходных коллекций — когда из нескольких коллекций создаётся новая коллекция того же тип без изменения изначальных.
str1 = 'abc'
str2 = 'de'
str3 = str1 + str2
print(str3) # abcde
tuple1 = (1, 2, 3)
tuple2 = (4, 5)
tuple3 = tuple1 + tuple2
print(tuple3) # (1, 2, 3, 4, 5)
a = [1, 2, 3]
b = [4, 5]
c = a + b
print(a, b, c) # [1, 2, 3] [4, 5] [1, 2, 3, 4, 5]
a = [1, 2, 3]
b = [4, 5]
c = a + [b]
print(a, b, c) # [1, 2, 3] [4, 5] [1, 2, 3, [4, 5]]
a, b = [1, 2, 3], [4, 5]
c = [*a, *b] # работает на версии питона 3.5 и выше
print(c) # [1, 2, 3, 4, 5]
Сложить два словаря чтобы получить третий оператором + Питон не позволяет «TypeError: unsupported operand type(s) for +: 'dict' and 'dict'».
Это можно сделать по-другому комбинируя методы .copy() и .update():
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = dict1.copy()
dict3.update(dict2)
print(dict3) # {'a': 1, 'c': 3, 'b': 2, 'd': 4}
В Питоне 3.5 появился новый более изящный способ:
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = {**dict1, **dict2}
print(dict3) # {'a': 1, 'c': 3, 'b': 2, 'd': 4}
Для обоих типов множеств (set, frozenset) возможны различные варианты комбинации множеств (исходные множества при этом не меняются — возвращается новое множество)
# Зададим исходно два множества (скопировать перед каждым примером ниже)
a = {'a', 'b'}
b = { 'b', 'c'} # отступ перед b для наглядности
c = a.union(b) # c = b.union(a) даст такой же результат
# c = a + b # Обычное объединение оператором + не работает
# TypeError: unsupported operand type(s) for +: 'set' and 'set'
print(c) # {'a', 'c', 'b'}
c = a.intersection(b) # c = b.intersection(a) даст такой же результат
print(c) # {'b'}
Пересечение более 2-х множеств сразу:
a = {'a', 'b'}
b = { 'b', 'c'}
c = { 'b', 'd'}
d = a.intersection(b, c) # Первый вариант записи
d = set.intersection(a, b, c) # Второй вариант записи (более наглядный)
print(d) # {'b'}
c = a.difference(b) # c = a - b другой способ записи дающий тот же результат
print(c) # {'a'}
c = b.difference(a) # c = b - a другой способ записи дающий тот же результат
print(c) # {'c'}
c = b.symmetric_difference(a)
# c = a.symmetric_difference(b) # даст такой же результат
print(c) # {'a', 'c'}
a.extend(b) # a += b эквивалентно a.extend(b)
print(a, b) # [1, 2, 3, 4, 5] [4, 5]
a.append(b) # a += [b] эквивалентно a.append(b)
print(a, b) # [1, 2, 3, [4, 5]] [4, 5]
dict1 = {'a': 1, 'b': 2}
dict2 = {'a': 100, 'c': 3, 'd': 4}
dict1.update(dict2)
print(dict1) # {'a': 100, 'c': 3, 'b': 2, 'd': 4}
a = {'a', 'b'}
b = { 'b', 'c'}
a.difference_update(b)
print(a, b) # {'a'} {'b', 'c'}
a = {'a', 'b'}
b = { 'b', 'c'}
b.difference_update(a)
print(a, b) # {'a', 'b'} {'c'}
a = {'a', 'b'}
b = { 'b', 'c'}
a.intersection_update(b)
print(a, b) # {'b'} {'b', 'c'}
a = {'a', 'b'}
b = { 'b', 'c'}
b.intersection_update(a)
print(a, b) # {'b', 'a'} {'b'}
a = {'a', 'b'}
b = { 'b', 'c'}
a.symmetric_difference_update(b)
print(a, b) # {'c', 'a'} {'c', 'b'}
a = {'a', 'b'}
b = { 'b', 'c'}
b.symmetric_difference_update(a)
print(a, b) # {'a', 'b'} {'c', 'a'}
Добавление и удаление элементов в коллекцию возможно только для изменяемых коллекций: списка (list), множества (только set, не frozenset), словаря (dict). Причём для списка, который является индексированной коллекцией, также важно на какую позицию мы добавляем элемент.
[7]
ПРИМЕЧАНИЯ:
my_list = [1, 2, 3]
my_list.insert(0, 0) # index = 0 - вставляем в начало
print(my_list) # [0, 1, 2, 3]
my_list.insert(10, 4) # Индекс выходит за границы списка - просто добавим в конец
print(my_list) # [0, 1, 2, 3, 4]
my_list.insert(-10, -1) # Индекс выходит за границы в минус - добавим в начало
print(my_list) # [-1, 0, 1, 2, 3, 4]
my_list = [1, 2, 3]
my_list.insert(1, 1.5) # Вставим между 1 и 2 (индексация с нуля!)
# То есть вставляется на позицию с указанным индексом, а то значение что на ней было
# и те что правее - сдвигаются на 1 индекс вправо
print(my_list) # [1, 1.5, 2, 3]
# Работает со списком
my_list = [1, 2, 3, 4, 5, 6, 7]
del my_list[1] # Удаление элемента по индексу
print(my_list) # [1, 3, 4, 5, 6, 7]
del my_list[-3:-1] # Удаление элементов выбранных срезом
print(my_list) # [1, 3, 4, 7]
# del my_list[10] # IndexError: list assignment index out of range
# Работает со словарем
my_dict = {'a': 1, 'b': 2, 'c': 3}
del my_dict['b']
print(my_dict) # {'a': 1, 'c': 3}
# del my_dict['z'] # KeyError при попытке удалить не сушествующий
str1 = 'abc'
print(str1, id(str1)) # abc 140234080454000
str1 += 'de'
print(str1, id(str1)) # abcde 140234079974992 - Это НОВЫЙ объект, с другим id!
Пример кода с двумя исходно идентичными строками.
str1 = 'abc'
str2 = str1
print(str1 is str2) # True - это две ссылки на один и тот же объект!
str1 += 'de' # Теперь переменная str1 ссылается на другой объект!
print(str1 is str2) # False - теперь это два разных объекта!
print(str1, str2) # abcde abc - разные значения
list1 = [1, 2, 3]
list2 = list1
print(list1 is list2) # True - это две ссылки на один и тот же объект!
# А дальше убеждаемся, насколько это важно:
list1 += [4]
print(list1, list2) # [1, 2, 3, 4] [1, 2, 3, 4]
# изменилось значение ОБЕИХ переменных, так как обе переменные ссылаются на один объект!
А если нужна независимая копия, с которой можно работать отдельно?
list1 = [1, 2, 3]
list2 = list(list1) # Первый способ копирования
list3 = list1[:] # Второй способ копирования
list4 = list1.copy() # Третий способ копировани - только в Python 3.3+
print(id(list1), id(list2), id(list3), id(list4))
# все 4 id разные, что значит что мы создали 4 разных объекта
list1 += [4] # меняем исходный список
print(list1, list2, list3, list4) # [1, 2, 3, 4] [1, 2, 3] [1, 2, 3] [1, 2, 3]
# как мы и хотели - изменив исходный объект, его копии остались не тронутыми
Автор: DaneSoul
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/235103
Ссылки в тексте:
[1] Python: коллекции, часть 2: индексирование, срезы, сортировка: https://habrahabr.ru/post/319200/
[2] Объединение множеств без изменения исходных.: #2
[3] Объединение списка, словаря и изменяемого множества с изменением исходной коллекции.: #3
[4] Добавление и удаление элементов изменяемых коллекций.: #4
[5] Особенности работы с изменяемой и не изменяемой коллекцией.: #5
[6] longclaps: https://habrahabr.ru/users/longclaps/
[7] Image: https://habrastorage.org/files/be6/e54/3a9/be6e543a942a45d6b80480c946deb583.png
[8] рассматривается во второй статье: https://habrahabr.ru/post/319200/#2
[9] Источник: https://habrahabr.ru/post/319876/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.