C foreach записать элементы в один массив. VBA циклы — For Next и For Each в Excel

Массив в языке Perl - это переменная, которая содержит в себе список значений. Имя переменной массива начинается с символа @. И это достаточно логично - символ @ основан на букве a, именно с этой буквы начинается слово array - массив.

Массив в Perl может хранить в себе список значений любых типов. Может быть массив в котором одновременно хранятся и строки, и числа, и что-нибудь еще.

Определение массива и доступ к элементам

Вот простой скрипт с примером определения и использования элементов массива в Perl:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); say $names; say $names;

Если запустить этот скрипт, то он выведет на экран:

Homer Bart

Что здесь происходит. Сначала стандартная строка с которой начинаются все Perl скрипты #!/usr/bin/perl, потом идет подключение (use) нескольких фич языка, которые делают работу с Perl удобнее. А потом создается переменная @names и ей присваивается список из 5 строк.

Как и во многих языках программирования в Perl первый элемент массива получает номер 0. После выполнения этой операции в переменной @names оказывается следующее:

  • в этой переменной под номером 0 хранится строка "Homer"
  • под номером 1 хранится строка "Marge"
  • 2 - "Bart"
  • 3 - "Lisa"
  • 4 - "Maggy"

Для того чтобы достать из переменной @name элемент с номером 2 используется совершенно идиотская форма - $name. Вот тут супер нелогично что символ @ заменятся на символ $ Официальное объяснение этой глупости - мы хотим получить доступ к одному элементу, а переменная с одним элементом начинается с символа $ Но это просто ошибка в дизайне языка. В Perl версии 6 это исправлено. Но в Perl версии 5 приходится жить с этим.

Say $names;

говорит - выводи на экран то что находится в массиве под номером 0. Под номером 0 в массиве находится строка "Homer" - она и появляется на экране.

Определение массивов. Дополнение.

Только что мы определи массив с помощью такого кода:

My @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie");

Когда элементов в массиве много, то удобнее их писать в столбик:

My @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie");

В языке Perl нет проблемы JSON - в Perl разрешено указывать запятую после последнего элемента:

My @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie",);

(На самом деле, если вы перечисляете элементы массива в столбик, то стоит всегда указывать запятую после последнего элемента - это делает проще работу с кодом и упрощает чтение diff).

Если в массиве находятся строки текста в которых нет пробелов, то есть еще более простой способ определить массив - использовать оператор qw:

My @names = qw(Homer Marge Bart Lisa Maggie);

Оператор qw разрезает текст который ему передан по пробельным символам и создает элементы списка.

Если нужно создать массив из списка чисел которые идут подряд, то можно использовать оператор..

My @array = (1..5);

Это то же самое что:

My @array = (1, 2, 3, 4, 5);

Оператор.. так же работает с буквами:

My @array = ("a".."z");

Эту фичу языка можно использовать в простом perl однострочнике, для генерации паролей:

$ perl -E "@c = ("a".."z", "A".."Z", 0..9); $s .= $c for (1..12); say $s" eIryv0884sp7

Вывод массивов

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

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); use Data::Dumper; say Dumper \@names;

Вот вывод этого скрипта:

$VAR1 = [ "Homer", "Marge", "Bart", "Lisa", "Maggie" ];

Если у вас есть Perl, то у вас библиотека Data::Dumper. Но если вы поставите дополнительно библиотеку Data::Printer, то для вывода содержимого массива придется писать меньше букв:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); use DDP; p \@names;

И вывод скрипта гораздо приятнее:

Длина массива

Задача. У нас есть массив @names, нужно узнать его размер - сколько в нем находится элементов. Есть несколько способов это сделать. Можно использовать специальную переменную в которой содержится индекс последнего элемента, а можно воспользоваться фичей Perl под названием "контекст".

Когда появляется массив, автоматически появляется специальная переменная, которая указывает на индекс последнего элемента. У нас есть массив @names в котором содержится 5 элементов и для него существует переменная $#names в которой содержится число 4 (так как элементы нумеруются с 0, а не с 1). Если количество элементов в массиве изменится, то автоматически изменится и $#names.

Первый способ узнать количество элементов в массиве - это взять $#names и прибавить единицу:

Say $#names + 1;

Этот способ работает и совершенно корректен, но более правильный способ - это использовать "контекст":

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); my $number = @names; say $number;

Что же здесь происходит? Сначала все то же самое что и в прошлом скрипте, но потом выполняется:

My $number = @names;

Мы создаем новую переменную $number В начале имени этой переменной находится символ $ - это означает что тип этой переменной - скаляр. Символ $ совершенно логичен - это символ похож на букву s с которой начинается слово scalar. Скаляр или скалярная переменная - это переменная в которой содержится только одно значение. Это может быть строка, число или что-нибудь еще.

И тут появляется контекст. Контекст - это весьма важная вещь в языке программирования Perl. В языке Perl в зависимости от контекста (т.е. от того что рядом) разные вещи действуют по разному. Контекст - это сложная вещь. Но для того чтобы программировать на Perl нужно разобраться ка работает контекст.

Выражение my $number = @names; означает что мы взяли массив и использовали его в "скалярном контексте". В скалярном контексте массива - это количество элементов в нем, т.е. ровно то что мы хотели получить.

Вот еще один пример использования контекста. Можно использовать массив в списочном контексте:

My ($man, $woman) = @names;

Результат этой операции - в скалярной переменной $man будет находится строка "Homer", а в скалярной переменной $woman будет находится строка "Marge".

В скрипте мы сначала присваивали массив в скалярную переменную, а потом выводили значение этой переменной:

My $number = @names; say $number;

А что будет если сразу вывести на экран значение массива @names ?

Say @names

Вот результат:

HomerMargeBartLisaMaggy

Такой вывод сильно отличается от числа 5. Объяснение этому - контекст. Ключевое слово say работает в списочном контексте. say выводит на экран все элементы списка который ей передали. Но можно явно указать что мы хотим работать с массивом в скалярном контексте:

Say scalar @names;

В этом случае вывод будет 5.

Работа с массивом

Бывают задачи когда нужно только создать массив, а дальше только читать из него значения. Но чаще встречаются задачи когда массив нужно изменять. Для этого есть несколько удобных функций.

Добавление элемента в конец массива:

My @arr = (1, 2, 3); push @arr, "abc";

Результат этой операции - в массиве @arr будет список (1, 2, 3, "abc");

С помощью push можно добавить в массив несколько элементов:

My @arr = (1, 2, 3); push @arr, "abc", "def";

Результат этой операции - в массиве @arr будет список (1, 2, 3, "abc", "def");

Интересная особенность push, про которую мало кто знает - эта функция не только меняет массив, но еще и возвращает число - сколько элементов стало в массиве после добавления в массив всех указанных элементов. Так что задачу "найти количество элементов в массиве" можно решить вот таким супер извращенным способом:

My $number = push(@arr, 1) - 1;

Функция push добавляет элемент (или элементы) в конец массива. В Perl есть функция для обратной операции - достать из массива последний элемент. Это делается с помощью функции pop (с помощью этой функции достать несколько элементов нельзя, эта функция достает только один элемент).

My @arr = (1, 2, 3); my $smth = pop @arr;

После выполнения кода выше массив @arr будет состоять из двух элементов (1, 2), а в переменной $smth будет находится число 3.

С помощью функций push/pop можно работать с массивом как со стеком.

Кроме функций push/pop, которые добавляют/убирают элементы в конце массива еще есть функции shift/unshift, которые работают с началом массива.

Добавить элемент в начало массива:

My @arr = (1, 2, 3); unshift @arr, "abc";

После выполнения этих команд в массиве @arr будет находится список ("abc", 1, 2, 3)

С помощью unshift можно добавить несколько элементов в начало массива:

My @arr = (1, 2, 3); unshift @arr, "abc", "def";

После выполнения этих команд в массиве @arr будет находится список ("abc", "def", 1, 2, 3)

Точно так же как push, unshift возвращает число - количество элементов в массиве после добавления туда всех элементов.

Достать из массива первый элемент можно с помощью функции shift:

My @arr = (1, 2, 3); my $element = shift @arr;

После выполнения этих действий массив станет состоять из двух элементов (2, 3), а в переменной $element будет бывший первый элемент массива - число 1.

  • unshift добавляет элемент/элементы в начало массива
  • shift достает элемент из начала массива
  • push добавляет элемент/элементы в конец массива
  • pop достает элемент из конца массива

Итерация по массиву

Часто бывают задача - нужно пробежаться по всем элементам массива и выполнить с ними какое-то действие.

В Perl, как и во множестве других языков программирования есть цикл for. Вот как пройти по всем элементам массива с помощью for:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); for (my $i = 0; $i <= $#names; $i++) { say $names[$i]; }

Вот вывод этой программы:

Homer Marge Bart Lisa Maggie

Тут все стандартно и просто. Определили $i = 0, проверили что условие выполняется, выполнили тело цикла, увеличили счетчик, проверили что условие выполняется, выполнили тело цикла, увеличили счетчик, ...

Но Perl предоставляет более простой и удобный способ итерации по массиву:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); foreach my $name (@names) { say $name; }

В этом варианте в переменную $name по очереди заносятся все элементы массива. Такой вариант проще и читать, и писать.

В Perl есть интересная фича - переменная по умолчанию. Если ну указать переменную для foreach, то perl будет заносить все элементы массива в переменную по умолчанию $_ :

Foreach (@names) { say $_; }

А если для say не указать никаких параметров, то say будет работать с переменной по умолчанию. Так что этот же цикл можно написать так:

Foreach (@names) { say; }

А еще в Perl можно использовать постфиксную запись для foreach, поэтому этот же цикл можно записать:

Say foreach @names;

В Perl есть цикл while, и его тоже можно использовать для итерации по массиву. Например так (аккуратно, в таком использовании кроется опасность):

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", "Maggie"); while (my $name = shift @names) { say $name; }

Конкретно этот пример работает точно так же как и другие варианты в этом разделе. Но если в массиве есть undef элементы, то этот цикл не пройдет по всем элементам:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", undef, "Maggie"); while (my $name = shift @names) { say $name; }

Вывод этого скрипта:

Homer Marge Bart Lisa

Т.е. без "Maggie". Можно переделать цикл while чтобы он работал корректно, например, так:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; my @names = ("Homer", "Marge", "Bart", "Lisa", undef, "Maggie"); while ($#names != -1) { my $name = shift @names; say $name if $name; }

(Переменная $#names возвращает -1 в том случае если массив пустой).

Но проще и понятнее это было бы написать с помощью foreach:

Foreach (@names) { say if $_; }

Функции

Массивы в Perl используются при написании собственных функций:

#!/usr/bin/perl use strict; use warnings FATAL => "all"; use feature "say"; sub say_hello { my ($name) = @_; say "Hello, ", $name; } say_hello "Homer";

Тут определяется функция с именем say_hello. Когда мы ее вызываем, то внутри функции все параметры которые мы в нее передали попадают в специальный массив @_.

С помощью записи

My ($name) = @_;

мы сохранили первый элемент массива @_ в переменную $name.

@_ - это массив, так что можно было работать с ним иначе. Например так:

Sub say_hello { say "Hello, ", $_; }

Sub say_hello { my $name = shift @_; say "Hello, ", $name; }

Если использовать shift внутри sub и не указать ей параметры, то она будет работать с @_. Так что последний вариант можно было записать:

Sub say_hello { my $name = shift; say "Hello, ", $name; }

При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.

— это непрерывный участок памяти, содержащий последовательность объектов одинакового типа, обозначаемый одним именем.

Массив характеризуется следующими основными понятиями:

Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти.
Каждый элемент массива характеризуется тремя величинами:

  • адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
  • индексом элемента (порядковым номером элемента в массиве);
  • значением элемента.

Адрес массива – адрес начального элемента массива.

Имя массива – идентификатор, используемый для обращения к элементам массива.

Размер массива – количество элементов массива

Размер элемента – количество байт, занимаемых одним элементом массива.

Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.

Представленный на рисунке массив содержит q элементов с индексами от 0 до q-1 . Каждый элемент занимает в памяти компьютера k байт, причем расположение элементов в памяти последовательное.

Адреса i -го элемента массива имеет значение

Адрес массива представляет собой адрес начального (нулевого) элемента массива. Для обращения к элементам массива используется порядковый номер (индекс) элемента, начальное значение которого равно 0 . Так, если массив содержит q элементов, то индексы элементов массива меняются в пределах от 0 до q-1 .

Длина массива – количество байт, отводимое в памяти для хранения всех элементов массива.

ДлинаМассива = РазмерЭлемента * КоличествоЭлементов

Для определения размера элемента массива может использоваться функция

int sizeof (тип);

Например,

sizeof (char ) = 1;
sizeof (int ) = 4;
sizeof (float ) = 4;
sizeof (double ) = 8;

Объявление и инициализация массивов

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

тип имя[размерность]={инициализация};

Инициализация представляет собой набор начальных значений элементов массива, указанных в фигурных скобках, и разделенных запятыми.

int a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // массив a из 10 целых чисел

Если количество инициализирующих значений, указанных в фигурных скобках, меньше, чем количество элементов массива, указанное в квадратных скобках, то все оставшиеся элементы в массиве (для которых не хватило инициализирующих значений) будут равны нулю. Это свойство удобно использовать для задания нулевых значений всем элементам массива.

int b = {0}; // массив b из 10 элементов, инициализированных 0


Если массив проинициализирован при объявлении, то константные начальные значения его элементов указываются через запятую в фигурных скобках. В этом случае количество элементов в квадратных скобках может быть опущено.

int a = {1, 2, 3, 4, 5, 6, 7, 8, 9};

При обращении к элементам массива индекс требуемого элемента указывается в квадратных скобках .

Пример на Си

1
2
3
4
5
6
7
8

#include
int main()
{
int a = { 5, 4, 3, 2, 1 }; // массив a содержит 5 элементов
printf("%d %d %d %d %d\n" , a, a, a, a, a);
getchar();
return 0;
}

Результат выполнения программы:

Однако часто требуется задавать значения элементов массива в процессе выполнения программы. При этом используется объявление массива без инициализации. В таком случае указание количества элементов в квадратных скобках обязательно.

int a;

Для задания начальных значений элементов массива очень часто используется параметрический цикл:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


#include
int main()
{
int a;
int i;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]);
}
// Вывод элементов массива
for (i = 0; i<5; i++)
printf("%d " , a[i]); // пробел в формате печати обязателен
getchar(); getchar();
return 0;
}

Результат выполнения программы

Многомерные массивы

В языке Си могут быть также объявлены многомерные массивы. Отличие многомерного массива от одномерного состоит в том, что в одномерном массиве положение элемента определяется одним индексом, а в многомерном - несколькими. Примером многомерного массива является матрица.

Общая форма объявления многомерного массива

тип имя[размерность1][размерность2]...[размерностьm];

Элементы многомерного массива располагаются в последовательных ячейках оперативной памяти по возрастанию адресов. В памяти компьютера элементы многомерного массива располагаются подряд, например массив, имеющий 2 строки и 3 столбца,

int a;


будет расположен в памяти следующим образом

Общее количество элементов в приведенном двумерном массиве определится как

КоличествоСтрок * КоличествоСтолбцов = 2 * 3 = 6.

Количество байт памяти, требуемых для размещения массива, определится как

КоличествоЭлементов * РазмерЭлемента = 6 * 4 = 24 байта.

Инициализация многомерных массивов

Значения элементов многомерного массива, как и в одномерном случае, могут быть заданы константными значениями при объявлении, заключенными в фигурные скобки {} . Однако в этом случае указание количества элементов в строках и столбцах должно быть обязательно указано в квадратных скобках .

Пример на Си

1
2
3
4
5
6
7
8
9

#include
int main()
{
int a = { 1, 2, 3, 4, 5, 6 };
printf("%d %d %d\n" , a, a, a);
getchar();
return 0;
}



Однако чаще требуется вводить значения элементов многомерного массива в процессе выполнения программы. С этой целью удобно использовать вложенный параметрический цикл .

Пример на Си

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a; // массив из 2 строк и 3 столбцов
int i, j;
// Ввод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("a[%d][%d] = " , i, j);
scanf("%d" , &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("%d " , a[i][j]);
}
printf("\n" ); // перевод на новую строку
}
getchar(); getchar();
return 0;
}



Передача массива в функцию

Обработку массивов удобно организовывать с помощью специальных функций. Для обработки массива в качестве аргументов функции необходимо передать

  • адрес массива,
  • размер массива.

Исключение составляют функции обработки строк, в которые достаточно передать только адрес.

При передаче переменные в качестве аргументов функции данные передаются как копии. Это означает, что если внутри функции произойдет изменение значения параметра, то это никак не повлияет на его значение внутри вызывающей функции.

Если в функцию передается адрес переменной (или адрес массива), то все операции, выполняемые в функции с данными, находящимися в пределах видимости указанного адреса, производятся над оригиналом данных, поэтому исходный массив (или значение переменной) может быть изменено вызываемой функцией.

Пример на Си Дан массив из 10 элементов. Поменять местами наибольший и начальный элементы массива. Для операций поиска максимального элемента и обмена использовать функцию.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#define _CRT_SECURE_NO_WARNINGS
#include
// Функция обмена
void change(int *x, int n)
{
// x - указатель на массив (адрес массива)
// n - размер массива
int i;
int max, index;
max = x;
index = 0;
// Поиск максимального элемента
for (i = 1; i {
if (x[i]>max)
{
max = x[i];
index = i;
}
}
// Обмен
x = x;
x = max;
}
// Главная функция
int main()
{
int a;
int i;
for (i = 0; i<10; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]);
}
change(a, 10); // вызов функции обмена
// Вывод элементов массива
for (i = 0; i<10; i++)
printf("%d " , a[i]);
getchar();
getchar();
return
p = p * x[i];
}
return p;
}
// Главная функция
int main()
{
int a; // объявлен массив a из 5 элементов
int i;
int pr;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]); // &a[i] - адрес i-го элемента массива
}
pr = func(a, 5); // вычисление произведения
printf("\n pr = %d" , pr); // вывод произведения четных элементов
getchar(); getchar();
return 0;
}



Иногда сложно найти в Сети правильные, а главное актуальные «best practices» для языка. Документация, конечно же, содержит всю необходимую информацию, но отсеять нужную вещь в абзацах подробного (на то она и документация) описания довольно сложно. Но недавно мне улыбнулся поиск Google, и я наткнулся на очень полезные «паттерны» языка Python от одного из core разработчиков - Raymond Hettinger.

Примечание : Все рекомендации даны в нескольких вариантах: сначала идут самые «плохие» варианты, а дальше предлагается лучшая альтернатива. Актуально для версии языка 2.7, отличия для версии 3.3 читайте в примечаниях к конкретному «паттерну».

Цикл по массиву из чисел
Плохо : иногда пишут так.
for i in : print i**2
Хорошо : лучший, с генератором. Но в 32 битной системе список из миллиона чисел будет занимать ~ 32 mb памяти.
for i in range(6): print i**2
Отлично: самый лучший вариант. В отличии от второго xrange возвращает только одно значение за раз, и не нужно лишнюю память для хранения всего массива.
for i in xrange(6): print i**2
Примечание : В версии Python 3.3 xrange уже в ядре и называеться просто range .
Цикл по списку
Плохо : часто бывшие С программисты пишут так.
colors = ["red", "green", "blue", "yellow"] for i in range(len(colors)): print colors[i]
Хорошо : лучший вариант.
colors = ["red", "green", "blue", "yellow"] for color in colors: print color
Но если нужно пройти по списку задом на перед?

Плохо : опять, прошло из C дает о себе знать:
colors = ["red", "green", "blue", "yellow"] for i in range(len(colors)-1, -1, -1): print colors[i]
Хорошо : но в Python пишут вот так:
colors = ["red", "green", "blue", "yellow"] for color in reversed(colors): print color

Цикл по списку с индексами
Плохо тоже что и выше.
colors = ["red", "green", "blue", "yellow"] for i in range(len(colors)): print i, "-->", colors[i]
Хорошо : более элегантный вариант:
colors = ["red", "green", "blue", "yellow"] for i, color in enumerate(colors): print i, "-->", color
Цикл по двум спискам
Плохо тоже что и выше.
names = ["raymond", "rachel", "matthew"] colors = ["red", "green", "blue", "yellow"] n = min(len(names), len(colors)) for i in range(n): print names[i], "-->", colors[i]
Хорошо : с двух списков делаем один список кортежей. Проблема в том что zip использует больше памяти чем первый вариант.
names = ["raymond", "rachel", "matthew"] colors = ["red", "green", "blue", "yellow"] for name, color in zip(names, colors): print name, "-->", color
Отлично : в отличии от zip , izip использует кэширование, что помогает существенно сэкономить память.
names = ["raymond", "rachel", "matthew"] colors = ["red", "green", "blue", "yellow"] for name, color in izip(names, colors): print name, "-->", color
Примечание : В версии Python 3.3 izip вписан в ядро и называется просто zip .
Сортировка списка по алгоритму
Плохо : используя функцию для сравнения.
colors = ["red", "green", "blue", "yellow"] def compare_length(c1, c2): if len(c1) < len(c2): return -1 if len(c1) > len(c2): return 1 return 0 print sorted(colors, cmp=compare_length)

Хорошо : используя сортировку по ключу. Использует намного меньше памяти.
colors = ["red", "green", "blue", "yellow"] print sorted(colors, key=len)
Примечание : Метод cmp убран с ядра Python 3.x.

Цикл по ключам словаря
Обычный способ возвращает ключи. При таком цикле происходит итерация словаря, поэтому в процессе его изменять нельзя.
for k in d: print k
Для изменения словаря в цикле используйте цикл по ключам (Пример: удаление всех ключей начинающихся с R):
for k in d.keys(): if k.startswith("R"): del d[k]
В этом случае d.keys() делает копию ключей словаря, что позволяет нам свободно работать с оригинальной структурой.
Цикл по ключам и значением словаря
Плохо : цикл по ключам и возвращение значение по последним. Медленный способ:
for k in d: print k, "-->", d[k]
Хорошо : быстрее делать цикл по значениях:
for k, v in d.items(): print k, "-->", v
Отлично : Но самый лучший и быстрый способ это использовать итератор:
for k, v in d.iteritems(): print k, "-->", v
Соединение двух списков в один словарь
Очень быстрый метод, используется только один кортеж для генерации словаря.
names = ["raymond", "rachel", "matthew"] colors = ["red", "green", "blue"] d = dict(izip(names, colors)) # d будет иметь следующее значение: # {"matthew": "blue", "rachel": "green", "raymond": "red"}
Подсчет элементов в словаре
Плохо : обычный способ:
colors = ["red", "green", "red", "blue", "green", "red"] d = {} for color in colors: if color not in d: d = 0 d += 1 #{"blue": 1, "green": 2, "red": 3}
Хорошо : использует функцию get() :
colors = ["red", "green", "red", "blue", "green", "red"] d = {} for color in colors: d = d.get(color, 0) + 1
Отлично : самый продвинутый способ это использовать defaultdict() . Но вы должны знать как он работает .
d = defaultdict(int) for color in colors: d += 1
Группирование элементов списка
Плохо : если нужно сгруппировать элементы списка по некоторому признаку (в примере - длина строки) часто используют такой метод:
names = ["raymond", "rachel", "matthew", "roger", "betty", "melissa", "judith", "charlie"] d = {} for name in names: key = len(name) if key not in d: d = d.append(name) {5: ["roger", "betty"], 6: ["rachel", "judith"], 7: ["raymond", "matthew", "melissa", "charlie"]}
Хорошо : но есть способ гораздо элегантней и быстрее:
d = defaultdict(list) for name in names: key = len(name) d.append(name)
Итог
На сегодня все. Надеюсь эти тривиальные, но полезные примеры помогут кому-то улучшить свой код, как они помогли это сделать мне. Их автором является Raymond Hettinger (

Цикл PHP foreach можно использовать следующим образом:

foreach($array_name as $value){ //код, который должен выполняться }

foreach($array_name as $key =>$value){ // //код, который должен выполняться }

Пример использования цикла foreach с числовым массивом

В этом примере мы создадим массив из пяти элементов с числовыми значениями. После этого цикл PHP foreach будет использован для выполнения итерации этого массива. Внутри цикла foreach мы использовали echo , чтобы вывести значения массива:

Посмотреть демо-версию и код

Пример с ключами и значениями массива

В этом примере описан другой способ использования цикла foreach PHP . Для этого мы создали ассоциативный массив из трех элементов. В него входят имена сотрудников (в качестве ключей ) и суммы заработной платы (в качестве значений ):


Посмотреть демо-версию и код

Пример изменения значения элемента массива в цикле foreach

Также можно c помощью PHP array foreach можно изменять значения элементов массива. Для этого используется «& » перед «$ » для переменной значения. Например:

&$value_of_element

Значение будет изменено. Чтобы вам было понятнее, рассмотрим следующий пример.

В этом примере мы создали числовой массив из пяти элементов. После этого использовали цикл foreach для отображения значений элементов.

Затем создали еще один цикл foreach , где перед $value_of_element добавляется «& «. Внутри фигурных скобок присваиваем новые значения элементам массива.

Чтобы увидеть разницу до и после присвоения новых значений, массив отображается с помощью функции print_r() .


Посмотреть демо-версию и код

Для чего используется цикл PHP foreach?

Цикл PHP foreach используется для работы с массивом. Он перебирает каждый его элемент.

Также можно использовать для работы с массивами цикл for . Например, используя свойство length , чтобы получить длину массива, а затем применить его в качестве оператора max . Но foreach делает это проще, так как он предназначен для работы с массивами.

Если вы работаете с MySQL , то для этого данный цикл подходит еще больше. Например, можно выбрать несколько строк из таблицы БД и передать их в массив. После этого, используя цикл foreach , перебрать все элементы массива с выполнением какого-либо действия.

Обратите внимание, что можно использовать цикл foreach с массивом или только с объектом.

Применение цикла foreach

В PHP существует два способа использования цикла foreach PHP. Оба описаны ниже.

  • Синтаксис первого метода использования:

foreach($array_name as $value){ echo $value }

При этом нужно указать имя массива, а затем переменную $value .

Для каждой итерации значение текущего элемента присваивается переменной $value . После завершения итерации переменной присваивается значение следующего элемента. И так до тех пор, пока все элементы массива не будут перебраны.

  • Синтаксис второго метода (PHP foreach as key value ):

Это подходит для ассоциативных массивов, в которых используются пары ключ / значение.

Во время выполнения каждой итерации значение текущего элемента будет присвоено переменной $value_of_element. Кроме этого ключ элемента присваивается переменной $key_of_element.

Если вы работаете с числовыми массивами, то можно использовать первый метод, в котором не нужны ключи элементов.

Перевод статьи «PHP foreach loop 2 ways to use it » был подготовлен дружной командой проекта .

Хорошо Плохо

Цикл For Each... Next в VBA Excel, его синтаксис и описание отдельных компонентов. Примеры использования цикла For Each... Next.

Цикл For Each... Next в VBA Excel предназначен для выполнения блока операторов по отношению к каждому элементу из группы элементов (диапазон, массив, коллекция). Этот замечательный цикл применяется, когда неизвестно количество элементов в группе и их индексация, в противном случае, более предпочтительным считается использование .

Синтаксис цикла For Each... Next

For Each element In group [ statements ] [ Exit For ] [ statements ] Next [ element ]

В квадратных скобках указаны необязательные атрибуты цикла For Each... Next.

Компоненты цикла For Each... Next

*Если цикл For Each... Next используется в VBA Excel для прохождения элементов коллекции (объект Collection) или массива, тогда переменная element должна быть объявлена с типом данных Variant , иначе цикл работать не будет.

**Если не использовать в цикле свой код, смысл применения цикла теряется.

Примеры циклов For Each... Next

Цикл для диапазона ячеек

На активном листе рабочей книги Excel выделите диапазон ячеек и запустите на выполнение следующую процедуру:

Sub test1() Dim element As Range, a As String a = "Данные, полученные с помощью цикла For Each... Next:" For Each element In Selection a = a & vbNewLine & "Ячейка " & element.Address & _ " содержит значение: " & CStr(element.Value) Next MsgBox a End Sub

Информационное окно MsgBox выведет адреса выделенных ячеек и их содержимое, если оно есть. Если будет выбрано много ячеек, то полностью информация по всем ячейкам выведена не будет, так как максимальная длина параметра Prompt составляет примерно 1024 знака.

Цикл для коллекции листов

Скопируйте следующую процедуру VBA в книги Excel:

Sub test2() Dim element As Worksheet, a As String a = "Список листов, содержащихся в этой книге:" For Each element In Worksheets a = a & vbNewLine & element.Index _ & ") " & element.Name Next MsgBox a End Sub

Информационное окно MsgBox выведет список наименований всех листов рабочей книги Excel по порядковому номеру их ярлычков, соответствующих их индексам.

Цикл для массива

Присвоим массиву список наименований животных и в цикле For Each... Next запишем их в переменную a . Информационное окно MsgBox выведет список наименований животных из переменной a .

Sub test3() Dim element As Variant, a As String, group As Variant group = Array("бегемот", "слон", "кенгуру", "тигр", "мышь") "или можно присвоить массиву значения диапазона ячеек "рабочего листа, например, выбранного: group = Selection a = "Массив содержит следующие значения:" & vbNewLine For Each element In group a = a & vbNewLine & element Next MsgBox a End Sub

Повторим ту же процедуру VBA, но всем элементам массива в цикле For Each... Next присвоим значение «Попугай». Информационное окно MsgBox выведет список наименований животных, состоящий только из попугаев, что доказывает возможность редактирования значений элементов массива в цикле For Each... Next.

Sub test4() Dim element As Variant, a As String, group As Variant group = Array("бегемот", "слон", "кенгуру", "тигр", "мышь") "или можно присвоить массиву значения диапазона ячеек "рабочего листа, например, выделенного: group = Selection a = "Массив содержит следующие значения:" & vbNewLine For Each element In group element = "Попугай" a = a & vbNewLine & element Next MsgBox a End Sub

Этот код, как и все остальные в этой статье, тестировался в Excel 2016.

Цикл для коллекции подкаталогов и выход из цикла

В этом примере мы будем добавлять в переменную a названия подкаталогов на диске C вашего компьютера. Когда цикл дойдет до папки Program Files , он добавит в переменную a ее название и сообщение: «Хватит, дальше читать не буду! С уважением, Ваш цикл For Each... Next.».

Sub test5() Dim FSO As Object, myFolders As Object, myFolder As Object, a As String "Создаем новый FileSystemObject и присваиваем его переменной "FSO" Set FSO = CreateObject("Scripting.FileSystemObject") "Извлекаем список подкаталогов на диске "C" и присваиваем "его переменной "myFolders" Set myFolders = FSO.GetFolder("C:\") a = "Папки на диске C:" & vbNewLine "Проходим циклом по списку подкаталогов и добавляем в переменную "a" "их имена, дойдя до папки "Program Files", выходим из цикла For Each myFolder In myFolders.SubFolders a = a & vbNewLine & myFolder.Name If myFolder.Name = "Program Files" Then a = a & vbNewLine & vbNewLine & "Хватит, дальше читать не буду!" _ & vbNewLine & vbNewLine & "С уважением," & vbNewLine & _ "Ваш цикл For Each... Next." Exit For End If Next Set FSO = Nothing MsgBox a End Sub

Информационное окно MsgBox выведет список наименований подкаталогов на диске C вашего компьютера до папки Program Files включительно и сообщение цикла о прекращении своей работы.

В результате работы программы будут выведены не только наименования подкаталогов, видимых при переходе в проводнике к диску C , но и скрытые и служебные папки. Для просмотра списка всех подкаталогов на диске C , закомментируйте участок кода от If до End If включительно и запустите выполнение процедуры в редакторе VBA Excel.



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: