Универсальные коллекции. Основные моменты.
Коллекции значений не могут храниться в базе данных(массив, таблица значений, список значений) и в большинстве случаев обладают одинаковым набором свойств и методов, создание большинства коллекций происходит с помощью метода Новый .
Обращение к элементам коллекции.
Элементами коллекции могут быть строки, колонки таблицы значений, элементы списка значений и тд. Обращаться к элементам коллекции возможно с помощью индекса, например:
важно знать, что индекс начинается с нуля. Можно обойти элементы коллекции в цикле, для этого существуют два варианта:
Как можно заметить здесь используется обращение к данным по индексу в цикле. Также очень удобно для любой коллекции использовать обход в цикле Для каждого . Например:
Здесь на каждом проходе цикла мы получаем следующее значение из коллекции.
Добавление и удаление элементов в коллекции
Для добавления элементов в коллекцию используется метод Добавить() который работает в большинстве случаев следующим образом:
Удаление значений из коллекции, происходит с помощью метода Удалить() для того что бы удалить значение из коллекции необходимо указать индекс или в некоторых случаях сам элемент коллекции, например:
удалит четвертую строку из массива. Для того, передать методу сам элемент коллекции, его нужно сначала получить или найти. Обычно это выглядит так:
То есть мы нашли сначала строку а потом ее передали в качестве аргумента методу Удалить() Для большинства коллекций доступен метод Очистить() который позволяет быстро удалить все значения из коллекции.
Список вопросов базы знаний
На рисунке представлена
При использовании режима «Сравнение, объединение с конфигурацией из файла» флажок «Разрешать удаление объектов основной конфигурации»…
Как определить виды документов, которые могут регистрироваться в качестве границы последовательности «СебестоимостьПродаж»?
На рисунке красным кружком отмечен
4.7. Основные приемы работы
Помимо основного обращения через точку, в языке системы «ЮПредприятие» предусмотрен механизм обращения к свойствам объектов но строке с именем свойства с помощью оператора [ j (квадратные скобки).
Такая конструкция позволяет обращаться к свойствам объектов гак же, как это делается через точку с указанием имени свойства.
Объект, к свойству которого идет обращение.
II Обращение к наименованию справочника по строке с именем свойства А = Спр[«Наименование»];
// Обращение к наименование справочника по имени свойства А = Спр.Наименование;
/I Оба эти обращения к свойству абсолютно равнозначны
Дополнение контекста объектов и форм
В языке еаь возможность при обращении к объектам и формам извне, из других программных модулей, обращаться к переменным, процедурам и функциям этих модулей, как к свойствам и методам самих объектов и форм.
// Припер использования процедуры печати документов из журнала // документов. Допустим, у нас есть несколько различных документов, // причем у всех есть процедура Печать!). В модуле журнала // документов располагается кнопка ‘Печать», которая I/ вызывает процедуру печати текущего документа журнала. Процедура ПечатьНажатие(элемент)
// Получим текущий документ, на котором установлен курсор. ТекДок — ЭлекентыФормы.ЖурналСпксок.ТекущаяСтрока;
II Получим основную форму текущего документа.
II Вызовем процедуру печати, расположенную //в модуле формы документа. ФрмТекДок.Печать();
Передача параметров процедур и функций
По умолчанию параметры методов, процедур и функций передаются по ссылке, то есть изменение внутри процедуры или функции значения формального параметра ведет к изменению значения соответствующего фактического параметра. При передаче параметра по значению изменение значения формального параметра никак не влияет на фактический параметр вызова процедуры. Для указания того, что тот или иной параметр следует передавать по значению, следует в исходном тексте процедуры или функции перед именем параметра записать ключевое слово Знач.
ВНИМАНИЕ! Если параметром передается агреіатньїіі объект, то невозможно присвоить фактическом) параметру другое значение, но возможно изменить сам переданный объект. Например, если в процедуру по значению передан массив, то можно очистить «тот массив методом Очистить О. но нельзя присвоить фактическому параметру ссылку на др\тои объект. Пример 2 (ниже) иллюстрирует ттх особенность.
Если параметру задано значение по умолчанию и он является последним в списке, го при вызове процедуры его можно опускать в списке передаваемых фактических параметров и не ставить запятую перед опушенным параметром.
Если параметру не задано значения но умолчанию, то при вызове процедуры его можно опускать н списке передаваемых фактических параметров, но разделительную запятую надо ставить.
Если параметр при вызове процедуры опушен, то он принимает либо установленное по умолчанию значение (если оно есть), либо значение
Если при вызове метода, процедуры или функции параметры не передаются (пустой список параметров), то, тем не менее, круглые скобки обязательно требуется ставить.
Перем Глоб; // Описание функции
Функция Подфункция(Знач Парі, Пар2, ПарЗ) Экспорт Лок = Глоб + Парі + Пар2 + ПарЗ; Парі » 40; Возврат1 Лок; КонецФункции;
Процедура МояПроцедура(Парі, Пар2, ПарЗ) Экспорт Лок « Глоб + Парі + Пар2 + ПарЗ; Парі — 40; КонецПроцедурыі
Глоб = 100; А = 10;
Реэ = МояФункция(А, 10, 10); // Вызов функции
II Здесь Реэ щ 130, а переменная А = 10, несмотря на то, что в теле П функции значение параметра Парі изменено на 40.
МояПроцедура(А, 10, 10); // Вызов процедуры II Здесь переменная А = 40, поскольку в теле II процедуры значение параметра Парі изменено на 40,
// Параметр перелается по значению Процедура МояПроцедура(Знач Параметр)
// В массиве два значения Параметр.Очистить();
II В массиве нет значений! II Меняем формальный параметр Параметр = 14;
// Изменено значение только формального параметра КонецПроцедуры
Массив = Новый МассиЕ,- Массив.Добавить(12); Массив .Добавить (18) ,// В массиве есть два элемента МояПроцедура(Массив);
// Массив пустой, но это по-прежнему массив, а не Число
Ряд объектов и языке системы «1С:Г1редприятие» представляет собой коллекции значений. Большинство коллекций имеют набор схожих методов и свойств, таких как Количество (), Индекс С), Добавить (), Удалить () и т.д. В качестве свойств коллекции, как правило, выступают ее элементы. Для коллекций доступен обход элементов коллекции посредством конструкции Для каждого- Из- Цикл. Дія большинства коллекции доступно обращение к элементам коллекции с помощью оператора [ ] (квадратные скобки). Как правило, в качестве аргумента передается индекс элемента коллекции. Индексирование элементов коллекции начинается с 0. Это означает, что индекс последнего элемента равен количеству элементов в коллекции минус !.
Если п процессе обхода коллекции происходит удаление или другие изменения состава элементов, то дальнейшее поведение системы неопределено.
Подробнее описание конкретных коллекции, их свойств, методов и приемов работы с ними см. в описаннях конкретных объектов. Использование номеров и индексов
В языке системы «1С:Предпрлятие» есть ряд объектов, отдельные части которых имеют нумерацию. К таким объектам, например, относится строка, символы которой имеют номер в строке, иди табличный документ, строки и колонки которого имеют номер, и т. и. При обращении к частям объектов обычно используется понятие Номер. Номера начинаются с I.
При обращении к элементам коллекций используется понятие Индекс. Индексирование элементов коллекций начинается с 0.
Работа с системными перечислениями
Во встроенном языке системы «1С:Предприятне» существует понятие системных перечислений. Они предназначены для определения некоторого ограниченного набора предопределенных значений. Доступ к системным перечислениям осуществляется как к свойствам глобального контекста его имени. Конкретные значения указываются через точку от имени системного перечисления. Системные перечисления используются, как правило, для задания значений параметров системных методов или свойств объектов, а также в качестве возвращаемых значений методов.
Работа с предопределенными значениями
Получить предопределенное значение на стороне сервера «1С:Предприятня» можно с помощью менеджера соответствующего объекта. Строка, определяющая получаемый реквизит, имеет следующий вид:
ТипПредопредєленіюгоЗначєния.ИмяОбъектаМетаданных.Значение Рассмотрим составляющие этой строки подробнее:
ТипПредопределенногсЗначения — для получения предопределенных значений доступно указание следующих типов данных (написание во множественном числе):
Имя О&ъектаМе та данных указывается имя объекта метаданных так. как оно задано в конфигу раторе.
Значение — может быть одним из следующих:
для перечислений укатывается имя значения перечисления,
дтя получения предопределенного значения указывается его имя, как оно задано в конфигураторе.
ТочкиМаршрута. ИмяТочки — точка маршрута бизнес-процесса.
В случае если требуется получить точку маршрута бизнес-процесса, строка, описывающая получаемое значение, будет выглядеть следу юшим образом:
II Получение значения перечисления. Вил » Перечисления.ВидыТоварой.Товар;
// Получение предопределенных данных справочника. Элемент = Справочники.Валюта.Рубль;
II Точка маршрута бизнес-процесса
4.7.7.2. С помощью функции ПредопределенноеЗначениеО
В связи с тем. что на стороне клиента недоступны прикладные объекты, получение предопределенных реквизитов с помощью менеджеров объектов становится невозможным. Поэтому для их получения существует метод глобального контекста ПредопределенноеЗначениеО. Параметром этою метода является строка, описывающая го, какое предопределенное значение требуется получить. Синтаксис описания предопределенного значения совпадает с синтаксисом оператора ЗНАЧЕНИЕ языка запросов (см.
Строка, определяющая получаемый реквизит, имеет следующий вид:
ТипПредопределенногоЗначения.ИмяОбъектаМетаданных.Значение Рассмотрим составляющие этой строки подробнее:
ТипПр- допределенногоЗначения — для получения предопределенных значений доступно указание следующих типов данных (написание в единственном числе):
ИмяОбгектаМетэданных — указывается имя объекта метаданных так, как оно задано в конфигураторе.
Значение — может быть одним из следующих:
для перечислений указывается имя значения перечисления,
для получения предопределенного значения указывается его имя. как оно задано в конфигураторе,
ТсчкаМаршрута. ИмяТочки — точка маршрута бизнес-процесса,
ПустаяСсылка — дія получения пустой ссылки.
В случае если требуется получить точку маршрута бизнес-процесса, строка, описывающая получаемое значение, будет выглядеть следующим образом:
// Получение значения перечисления.
Вид = ПредопределенноеЗначение («Перечисление.ВидыТоваров.Товар»)
// Получение значения пустой ссылки. ПустаяСсылка ПредопределенноеЗначение («Документ. РасходнаяНакл .ПустаяСсылка»>
П Получение предопределенных данных справочника.
II Точка маршрута бизнес-процесса
Точка = ПредопределенноеЗначение(«БизнесПроцесс.Согласование, ТочкаМаршрута.Одобрение») ,
Python: коллекции, часть 2/4: индексирование, срезы, сортировка
В данной статье мы продолжим изучать общие принципы работы со стандартными коллекциями (модуль collections в ней не рассматривается) Python.
Для кого: для изучающих Python и уже имеющих начальное представление о коллекциях и работе с ними, желающих систематизировать и углубить свои знания, сложить их в целостную картину.
ОГЛАВЛЕНИЕ:
- Индексирование
1. Индексирование
1.1 Индексированные коллекции
Рассмотрим индексированные коллекции (их еще называют последовательности — sequences) — список (list), кортеж (tuple), строку (string).
Под индексированностью имеется ввиду, что элементы коллекции располагаются в определённом порядке, каждый элемент имеет свой индекс от 0 (то есть первый по счёту элемент имеет индекс не 1, а 0) до индекса на единицу меньшего длины коллекции (т.е. len(mycollection)-1).
1.2 Получение значения по индексу
Для всех индексированных коллекций можно получить значение элемента по его индексу в квадратных скобках. Причем, можно задавать отрицательный индекс, это значит, что будем находить элемент с конца считая обратном порядке.
При задании отрицательного индекса, последний элемент имеет индекс -1, предпоследний -2 и так далее до первого элемента индекс которого равен значению длины коллекции с отрицательным знаком, то есть (-len(mycollection).
элементы | a | b | c | d | e |
---|---|---|---|---|---|
индексы | 0 (-5) | 1 (-4) | 2 (-3) | 3 (-2) | 4 (-1) |
Наши коллекции могут иметь несколько уровней вложенности, как список списков в примере ниже. Для перехода на уровень глубже ставится вторая пара квадратных скобок и так далее.
1.3 Изменение элемента списка по индексу
Поскольку кортежи и строки у нас неизменяемые коллекции, то по индексу мы можем только брать элементы, но не менять их:
А вот для списка, если взятие элемента по индексу располагается в левой части выражения, а далее идёт оператор присваивания =, то мы задаём новое значение элементу с этим индексом.
UPD: Примечание: Для такого присвоения, элемент уже должен существовать в списке, нельзя таким образом добавить элемент на несуществующий индекс.
2 Срезы
2.1 Синтаксис среза
Очень часто, надо получить не один какой-то элемент, а некоторый их набор ограниченный определенными простыми правилами — например первые 5 или последние три, или каждый второй элемент — в таких задачах, вместо перебора в цикле намного удобнее использовать так называемый срез (slice, slicing).
Следует помнить, что взяв элемент по индексу или срезом (slice) мы не как не меняем исходную коллекцию, мы просто скопировали ее часть для дальнейшего использования (например добавления в другую коллекцию, вывода на печать, каких-то вычислений). Поскольку сама коллекция не меняется — это применимо как к изменяемым (список) так и к неизменяемым (строка, кортеж) последовательностям.
Синтаксис среза похож на таковой для индексации, но в квадратных скобках вместо одного значения указывается 2-3 через двоеточие:
Особенности среза:
- Отрицательные значения старта и стопа означают, что считать надо не с начала, а с конца коллекции.
- Отрицательное значение шага — перебор ведём в обратном порядке справа налево.
- Если не указан старт [:stop:step]— начинаем с самого края коллекции, то есть с первого элемента (включая его), если шаг положительный или с последнего (включая его), если шаг отрицательный (и соответственно перебор идет от конца к началу).
- Если не указан стоп [start:: step] — идем до самого края коллекции, то есть до последнего элемента (включая его), если шаг положительный или до первого элемента (включая его), если шаг отрицательный (и соответственно перебор идет от конца к началу).
- step = 1, то есть последовательный перебор слева направо указывать не обязательно — это значение шага по умолчанию. В таком случае достаточно указать [start:stop]
- Можно сделать даже так [:] — это значит взять коллекцию целиком
- ВАЖНО: При срезе, первый индекс входит в выборку, а второй нет!
То есть от старта включительно, до стопа, где стоп не включается в результат. Математически это можно было бы записать как [start, stop) или пояснить вот таким правилом:
Примеры срезов в виде таблицы:
2.2. Именованные срезы
Чтобы избавится от «магических констант», особенно в случае, когда один и тот же срез надо применять многократно, можно задать константы с именованными срезами с пользованием специальной функции slice()()
Примечание: Nonе соответствует опущенному значению по-умолчанию. То есть [:2] становится slice(None, 2), а [1::2] становится slice(1, None, 2).
2.3 Изменение списка срезом
Важный момент, на котором не всегда заостряется внимание — с помощью среза можно не только получать копию коллекции, но в случае списка можно также менять значения элементов, удалять и добавлять новые.
Проиллюстрируем это на примерах ниже:
- Даже если хотим добавить один элемент, необходимо передавать итерируемый объект, иначе будет ошибка TypeError: can only assign an iterable
2.4 Выход за границы индекса
Обращение по индексу по сути является частным случаем среза, когда мы обращаемся только к одному элементу, а не диапазону. Но есть очень важное отличие в обработке ситуации с отсутствующим элементом с искомым индексом.
Обращение к несуществующему индексу коллекции вызывает ошибку:
А в случае выхода границ среза за границы коллекции никакой ошибки не происходит:
Примечание: Для тех случаев, когда функционала срезов недостаточно и требуются более сложные выборки, можно воспользоваться синтаксисом выражений-генераторов, рассмотрению которых посвещена 4 статья цикла.
3 Сортировка элементов коллекции
Сортировка элементов коллекции важная и востребованная функция, постоянно встречающаяся в обычных задачах. Тут есть несколько особенностей, на которых не всегда заостряется внимание, но которые очень важны.
3.1 Функция sorted()
Мы может использовать функцию sorted() для вывода списка сортированных элементов любой коллекции для последующее обработки или вывода.
- функция не меняет исходную коллекцию, а возвращает новый список из ее элементов;
- не зависимо от типа исходной коллекции, вернётся список (list) ее элементов;
- поскольку она не меняет исходную коллекцию, ее можно применять к неизменяемым коллекциям;
- Поскольку при сортировке возвращаемых элементов нам не важно, был ли у элемента некий индекс в исходной коллекции, можно применять к неиндексированным коллекциям;
- Имеет дополнительные не обязательные аргументы:
reverse=True — сортировка в обратном порядке
key=funcname (начиная с Python 2.4) — сортировка с помощью специальной функции funcname, она может быть как стандартной функцией Python, так и специально написанной вами для данной задачи функцией и лямбдой.
Пример сортировки списка строк по длине len() каждого элемента:
3.2 Функция reversed()
Функция reversed() применяется для последовательностей и работает по другому:
- возвращает генератор списка, а не сам список;
- если нужно получить не генератор, а готовый список, результат можно обернуть в list() или же вместо reversed() воспользоваться срезом [: :-1];
- она не сортирует элементы, а возвращает их в обратном порядке, то есть читает с конца списка;
- из предыдущего пункта понятно, что если у нас коллекция неиндексированная — мы не можем вывести её элементы в обратном порядке и эта функция к таким коллекциям не применима — получим «TypeError: argument to reversed() must be a sequence»;
- не позволяет использовать дополнительные аргументы — будет ошибка «TypeError: reversed() does not take keyword arguments».
3.3 Методы списка .sort() и .reverse()
У списка (и только у него) есть особые методы .sort() и .reverse() которые делают тоже самое, что соответствующие функции sorted() и reversed(), но при этом:
- Меняют сам исходный список, а не генерируют новый;
- Возвращают None, а не новый список;
- поддерживают те же дополнительные аргументы;
- в них не надо передавать сам список первым параметром, более того, если это сделать — будет ошибка — не верное количество аргументов.
Обратите внимание: Частая ошибка начинающих, которая не является ошибкой для интерпретатора, но приводит не к тому результату, который хотят получить.
3.4 Особенности сортировки словаря
В сортировке словаря есть свои особенности, вызванные тем, что элемент словаря — это пара ключ: значение.
UPD: Так же, не забываем, что говоря о сортировке словаря, мы имеем ввиду сортировку полученных из словаря данных для вывода или сохранения в индексированную коллекцию. Сохранить данные сортированными в самом стандартном словаре не получится, они в нем, как и других неиндексированных коллекциях находятся в произвольном порядке.
- sorted(my_dict) — когда мы передаем в функцию сортировки словарь без вызова его дополнительных методов — идёт перебор только ключей, сортированный список ключей нам и возвращается;
- sorted(my_dict.keys()) — тот же результат, что в предыдущем примере, но прописанный более явно;
- sorted(my_dict.items()) — возвращается сортированный список кортежей (ключ, значение), сортированных по ключу;
- sorted(my_dict.values()) — возвращается сортированный список значений
Отдельные сложности может вызвать сортировка словаря не по ключам, а по значениям, если нам не просто нужен список значений, и именно выводить пары в порядке сортировки по значению.
Для решения этой задачи можно в качестве специальной функции сортировки передавать lambda-функцию lambda x: x[1] которая из получаемых на каждом этапе кортежей (ключ, значение) будет брать для сортировки второй элемент кортежа.
UPD от ShashkovS: 3.5 Дополнительная информация по использованию параметра key при сортировке
Допустим, у нас есть список кортежей названий деталей и их стоимостей.
Нам нужно отсортировать его сначала по названию деталей, а одинаковые детали по убыванию цены.
Перед тем, как сравнивать два элемента списка к ним применялась функция prepare_item, которая меняла знак у стоимости (функция применяется ровно по одному разу к каждому элементу. В результате при одинаковом первом значении сортировка по второму происходила в обратном порядке.
Чтобы не плодить утилитарные функции, вместо использования сторонней функции, того же эффекта можно добиться с использованием лямбда-функции.
- (на английском). — еще один комментарий с детальным примером ShashkovS к данной статье
UPD от ShashkovS: 3.6 Устойчивость сортировки
Допустим данные нужно отсортировать сначала по столбцу А по возрастанию, затем по столбцу B по убыванию, и наконец по столбцу C снова по возрастанию.
Если данные в столбце B числовые, то при помощи подходящей функции в key можно поменять знак у элементов B, что приведёт к необходимому результату.
А если все данные текстовые? Тут есть такая возможность.
Дело в том, что сортировка sort в Python устойчивая (начиная с Python 2.2), то есть она не меняет порядок «одинаковых» элементов.