Цикл for с двумя переменными с: Вариации цикла for | Программирование на C и C++

python — цикл for с двумя переменными

Вопрос задан

Изменён 11 месяцев назад

Просмотрен 360 раз

Хочу внутри одного цикла, с двумя переменными, с помощью принтов выводить ссылки + цену. Сейчас всё валится с ошибкой, чё то не могу понять в какую сторону смотреть. Если разделять на два цикла, то по отдельности всё нормально работает. Подскажите куда смотреть.

request = requests.get(url)
bs = BeautifulSoup(request.text, "html.parser")
all_links = bs.find_all("a", class_="link-link-MbQDP link-design-default-_nSbv title-root-j7cja iva-item-title-_qCwt title-listRedesign-XHq38 title-root_maxHeight-SXHes")
all_links1 = bs.find_all("meta", itemprop="price")
# for link1 in all_links1:     #
#     print(link1['content'])  #
#                              # отдельно всё работает, но создаётся соответственно два списка
# for link in all_links:       #
#     print(link['href'])      #
for link in all_links, all_links1:
    print(link["href"] + link["content"])

print(link["href"] + link["content"])

TypeError: list indices must be integers or slices, not str

  • python
  • python-3. x

2

Я могу рассказать на примере Авито, тоже недавно парсил. В общем, тебе нужно сначала найти весь блок объявлений, а потом раскладывать их на части. Как сделал я: data = bs.find("div", class_="items-items-kAJAg").find_all("div", class_="iva-item-root-Nj_hb") Поясню: find() — вернул мне весь(то есть ОДИН) блок, со всеми объявлениями, затем find_all() — вернул мне ВСЕ объявления, которые есть в блоке, который мы искали при помощи find(). Получается как-то сложно, либо я не умею объяснять. На скрине ОДИН видно, что я выбрал блок со ВСЕМИ объявлениями, затем нужно записать его класс в find(), а потом, как я сделал на скрине ДВА, выбрать одно объявление и записать его класс в find_all(). Затем циклов for перебирать всю что входит в переменную data

    for value1 in data:
        try:
            title = value1.find("h4", itemprop="name").text.strip()
        except:
            title = ""
        try:
            price = value1. find("span", class_="price-text-E1Y7h").text.strip().replace("\xa0", "")
            #print(price)
        except:
            price = ""
        try:
            link = "https://www.avito.ru/" + value1.find("a", class_="iva-item-title-_qCwt")["href"]
        except:
            link = ""

Вот, переменные по типу title, price и link естественно можно менять на свои.

P.s: Это был мой первый ответ на форуме, не суди строго, как смог — так объяснил.

1

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

python — Проблема с двумя переменными в while

Вопрос задан

Изменён 4 года 4 месяца назад

Просмотрен 118 раз

Есть код, суть которого заключается в разбиении уравнения(строки) на переменные(-abc+3a+4ac+2ac = [-abc, 3a, 4ac, 2ac]). Столкнулся со сложностью в функции while. При 2 переменных она работает не корректно(должна завершаться при -1 у обоих переменных, но завершается как хочет, было и при 0,4). В интернете только примеры с одной переменной, мб она и не может 2 переменных содержать, поэтому решил спросить: Может ли и что не так?

def simplify(p):
    e = []
    q = p.find('-')
    w = p.find('+')
    while w and q  != -1:
        if q < w:
            if q == -1 or q == 0:
                e.append(p[:w])
                p = p[w+1:]
                q = p.find('-')
                w = p.find('+')
            else:
                e.append(p[:q])
                p = p[q:]
                q = p.find('-')
                w = p.find('+')
        else:
            if w == -1:
                if q == 0:
                    break
                e.append(p[:q])
                p = p[q:]
                q = p.find('-')
                w = p.find('+')
            else:
                e.append(p[:w])
                p = p[w+1:]
                q = p.
find('-') w = p.find('+') e.append(p) return e print(simplify("-abc+3a+4ac+2ac "))

Также есть еще вопрос: можно ли в if/elif/else делать ссылки на другой if. Например действия при «if q == -1 or q == 0» и действия при последнем в цикле else одинаковы:

e.append(p[:w])
p = p[w+1:]
q = p.find('-')
w = p.find('+')

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

  • python
  • python-3.x
  • while
  • логические-выражения

1

Вот так должно быть:

while (w != -1) and (q != -1):

А то, что в коде — совсем другое.

Чтобы получить из "-abc+3a+4ac+2ac "

['-abc', '3a', '4ac', '2ac '] достаточно манипуляций:

t = "-abc+3a+4ac+2ac "
tt = t. replace("-", "+-")
ttt = [x for x in tt.split("+") if bool(x)]
print ttt
# ['-abc', '3a', '4ac', '2ac ']

Ваш вопрос касательно ссылки на if. Условия первичны, код под ними вторичен. Т.о. в вашем варианте, чтобы не дублировать код, блок под if можно поместить в функцию.

def f(x, y):
    <блок кода>
if <условие>:
    if <условие>:
        f(1, 1)
    else:
        f(1, 0)
else:
    if <условие>:
        f(0, 1)
    else:
        f(0, 0)

Ну или придумывать логику как избавить от определённых условий, включив их в другие, сделать дерево ветвления одномерным — без вложенности и пр.

Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации

Почта

Необходима, но никому не показывается

Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки

Можете ли вы объявить несколько переменных в цикле for на C++?

Объявление переменной означает идентификацию области памяти для содержимого переменной. Что ж, ответ: да. Начните с рассмотрения следующего сегмента кода:

    int i = 0;
    int j = 0;
    int k = 0;

Это три оператора, которые можно записать в один оператор, как:

    int i = 0, j = 0, k = 0;

Имеется один тип данных; выражения разделяются запятыми. Оператор заканчивается одной точкой с запятой. Несколько переменных были объявлены здесь в одном операторе.

Теперь рассмотрим следующие операторы приращения:

    int i++;
    int j++;
    int k++;

Эти три оператора можно заменить одним оператором следующим образом:

    int i++, j++, k++;

Здесь три выражения в одном операторе для одного типа данных.

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

    i < 10;
    j < 10;

    k < 10;

Эти три оператора можно заменить одним оператором следующим образом:

    i < 10 && j < 10 && k < 10;

Здесь три оператора объединены в одно выражение особой формы. Эти выражения не разделяются запятыми, как в приведенных выше случаях, а объединяются логическим И.

В этой статье объясняется, как можно объявлять и использовать несколько переменных в цикле for с обычными соответствиями. Для иллюстраций используются очень простые примеры.

Содержание статьи

  • Одномерный цикл for
  • Двухмерный цикл for
  • Трехмерный цикл for
  • Возможное преимущество
  • Заключение

Одномерный цикл for

Цикл while

Цикл while для отображения чисел от нуля до 9, как в следующей программе:

    #include
    using namespace std;

    int main()
    {
        int i=0;

        while (i < 10) {
            cout << i << endl;
            i++;
        }
     
        вернуть 0;
    }

Первая строка программы включает библиотеку iostream для объекта cout. Следующая строка в программе — оператор. Это гарантирует, что любое используемое имя взято из стандартной библиотеки C++, если не указано иное.

В функции main() есть оператор инициализации целого числа, i = 0. Затем есть цикл while, который учитывает оператор инициализации. Условие while (i < 10), и пока i меньше 10 (никогда не равно 10), объект cout iostream в теле цикла while отображает значение i. Следующий оператор в цикле while увеличивает i (добавляет 1 к значению i).

Вывод выглядит следующим образом, но отображается вертикально:

    0 1 2 3 4 5 6 7 8 9

Одномерный цикл for

Код функции main() выше воспроизводится в следующей программе: как цикл for:

    #include
    using namespace std;

    int main()
    {
        for (int i = 0; i < 10; i++) {
            cout << i << endl;
        }
     
        вернуть 0;
    }

Вывод такой же, как и в предыдущем случае. Оператор инициализации для приведенного выше кода теперь является первым оператором в скобках цикла for, за которым следует точка с запятой. Условие while для приведенного выше кода теперь является вторым оператором в скобках цикла for, за которым следует точка с запятой. Оператор приращения в теле цикла while для предыдущего кода теперь является третьим оператором в круглых скобках цикла for. За ним не следует точка с запятой, потому что это последний оператор в круглых скобках. Единственный оператор в цикле for отображает значение i.

Двухмерный цикл for


Вложенный цикл while

Приведенный выше одномерный цикл for отображает один столбец, где каждая ячейка имеет число, значение i. Цикл while, вложенный в другой цикл while, будет отображать таблицу, где каждая ячейка будет иметь число (значение j в этой позиции). Следующая программа иллюстрирует это:

    #include
    using namespace std;

    int main()
    {
        int i=0;
        пока (i < 5) {
            int j=0;
            while (j < 5) {
                cout << j << ' ';
                j++;
            }
            cout << endl;
            i++;
        }
     
        вернуть 0;
}

Выход:

0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4

Переменная I определяет строки. Переменная j определяет столбцы. Максимальные значения для i и j в этом коде равны 4. Значение i не печатается. Для каждого значения j значение j напечатано горизонтально. j увеличивается, чтобы печатать следующее значение по горизонтали для каждой строки.

Имеется два оператора инициализации: один для i и один для j, оба инициализированы нулем. Оператор инициализации для j находится во внешнем цикле. Таким образом, j повторно инициализируется для каждой строки (каждой горизонтальной строки). Таким образом, j может производить числа от 0 до 4 для каждой строки. Значение i никогда не печатается; он указывает только номер строки. i увеличивается снаружи и ниже вложенного цикла. i увеличивается для следующей строки.

Вложенный цикл for

Следующий вложенный цикл for дает тот же результат (таблицу), что и предыдущий вложенный цикл while:

    #include
    using namespace std;

    int main()
    {         for (int i=0; i < 5; i++) {
            for (int j=0; j < 5; j++) {
                  cout j << ';
            }
            cout << endl;
        }
     
        вернуть 0;
    }

Каждая скобка цикла for имеет свой собственный оператор инициализации, свой собственный оператор условия и свой собственный оператор приращения.

Один цикл while

Приведенный выше вывод таблицы может быть получен с помощью одного цикла while с одним оператором инициализации и одним оператором условия. Однако повторное присвоение нуля j и увеличение i должно происходить в конструкции if. Следующий код иллюстрирует это:

    #include
    using namespace std;

    int main()
    {
        int i=0, j=0;
        while (i < 5 && j <5) {
            cout << j << ' ';
            j++;
            if (j == 5) {
                cout << endl;
                j=0;
                i++;
            }
        }
     
        вернуть 0;
    }

Результатом является та же таблица, что и выше.

Один цикл for

Приведенные выше выходные данные таблицы могут быть созданы одним циклом for с одним оператором инициализации и одним оператором условия. Однако повторное присвоение нуля j и увеличение i должно происходить в конструкции if. Следующая программа иллюстрирует это:

    #include
    using namespace std;

    int main()
    {
        for (int i=0, j=0; i < 5 && j <5; j++) {
            cout << j << ' ';
            if (j == 4) {
                cout << endl;
                j = -1;
                i++;
            }
        }
     
        вернуть 0;
    }

Результатом является та же таблица, что и выше. Однако здесь, поскольку j увеличивается в конце цикла, в круглых скобках условие if (j == 4), а j переназначается, -1 для каждой строки.

Что здесь особенного, так это то, что две переменные были объявлены в цикле for. Таким образом, в цикле for может быть объявлено несколько переменных.

Адресация по ведущей диагонали

В квадратной таблице ведущая диагональ — это диагональ от верхнего левого края до нижнего правого края. Следующая программа отображает координаты первой диагонали приведенной выше таблицы:

    #include
    using namespace std;

    int main()
    {
        for (int i=0, j=0; i < 5 && j <5; i++,j++) {
            cout << i << ',' << j << ' ';
        }
        cout << endl;
     
        вернуть 0;
    }

Вывод:

    0,0 1,1 2,2 3,3 4,4

Обратите внимание, что в программе в скобках цикла for объявлены две переменные; условие имеет две переменные, связанные логическим И; а оператор приращения имеет две переменные, каждая из которых увеличивается путем добавления единицы. При этом условии единственный оператор в теле цикла for печатает координаты ведущей диагонали.

Трехмерный цикл for

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

    #include
    using namespace std;

    int main()
    {           for (int i=0,j=0,k=0; i<5&&j<5&&k<5; i++,j++,k++) {
            cout << i << ',' < < j << ',' << k << ' ';
        }
        cout << endl;
     
        вернуть 0;
    }

Вывод:

    0,0,0 1,1,1 2,2,2 3,3,3 4,4,4

Обратите внимание, что оператор инициализации имеет три переменные; оператор условия имеет три переменные, а оператор приращения имеет три переменные. В теле цикла for есть только один оператор.

Возможное преимущество

Рассмотрим один цикл for для отображения всех значений ячеек квадратной таблицы:
Наличие двух переменных в операторе инициализации и в условии не дает никакого преимущества в скорости по сравнению с ситуацией, когда один цикл вложен.

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

    #include
    using namespace std;

    int main()
    {           for (int i=0, j=0; i < 10 && j <10; i+=2,j+=2) {
            cout << i << ',' << j << ' ';
        }
        cout << endl;
     
        вернуть 0;
    }

Вывод:

    0,0 2,2 4,4 6,6 8,8

В цикле for остается только одна инструкция. Таким образом, получение преимущества в скорости включает в себя включение дополнительной выборочной логики в оператор условия и/или в оператор приращения. Выражения инициализации в операторе инициализации, возможно, не нужно инициализировать нулем.

В приведенном выше коде оператор приращения выглядит следующим образом:

    i+=2,j+=2

, что означает

    i = i+2, j = j+2;

Заключение

Да, я могу объявить несколько переменных в цикле for. Теперь вы тоже можете объявить несколько переменных в цикле for следующим образом: просто разделите несколько переменных в операторе инициализации запятыми. Не забудьте закончить полный оператор инициализации точкой с запятой. Если доступ к элементам структуры должен быть выборочным, то эти переменные, возможно, также придется использовать в операторах условия и/или приращения, в круглых скобках цикла for, возможно, с некоторой дополнительной логикой.

python — «для цикла» с двумя переменными?

На этот вопрос уже есть ответы здесь :

Как выполнить итерацию по двум спискам параллельно? (8 ответов)

Закрыта 2 года назад.

Как я могу включить две переменные в один и тот же для петля?

 t1 = [список целых чисел, строк и списков]
t2 = [другой список целых чисел, строк и списков]
def f(t): #функция, которая будет читать списки "t1" и "t2" и возвращать все идентичные элементы
    для i в диапазоне (len (t1)) и для j в диапазоне (len (t2)):
        ...
 
  • питон
  • для цикла

11

Если вам нужен эффект вложенного цикла for, используйте:

 import itertools
для i, j в itertools.product (диапазон (x), диапазон (y)):
    # Вещи...
 

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

 для i, j в zip (диапазон (x), диапазон (y)):
    # Вещи...
 

Обратите внимание, что если x и y имеют разную длину, zip будет усечен до самого короткого списка. Как отметил @abarnert, если вы не хотите обрезать до самого короткого списка, вы можете использовать itertools. zip_longest .

ОБНОВЛЕНИЕ

Основываясь на запросе «функции, которая будет читать списки «t1» и «t2» и возвращать все идентичные элементы», я не думаю, что OP хочет почтовый индекс или продукт . Я думаю, что им нужен набор :

 def equal_elements(t1, t2):
    список возврата (набор (t1). пересечение (набор (t2)))
    # Вы также можете сделать
    # возвращаемый список(set(t1) & set(t2))
 

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

ОБНОВЛЕНИЕ 2

ИЛИ, OP может захотеть, чтобы элементы, идентичные , находились в одной и той же позиции в списках . В этом случае zip был бы наиболее подходящим, и тот факт, что он усекается до самого короткого списка, — это то, что вам нужно (поскольку невозможно, чтобы один и тот же элемент был в индексе 9когда один из списков состоит всего из 5 элементов). Если это то, что вы хотите, сделайте следующее:

 def equal_elements(t1, t2):
    вернуть [x для x, y в zip (t1, t2), если x == y]
 

Будет возвращен список, содержащий только те элементы, которые одинаковы и находятся в одном и том же положении в списках.

12

Здесь возможны два вопроса: как вы можете перебирать эти переменные одновременно или как вы можете перебирать их комбинация .

К счастью, есть простые ответы на оба вопроса. В первом случае вы хотите использовать zip .

 х = [1, 2, 3]
у = [4, 5, 6]
для i, j в zip(x, y):
   печать (стр (i) + " / " + строка (j))
 

будет выводить

 1 / 4
2 / 5
3 / 6
 

Помните, что вы можете поместить любой итерируемый в zip , поэтому вы можете так же легко написать свой пример, например:

 для i, j в zip(range(x), range(y)):
    # работай здесь. 
 

На самом деле, только что понял, что это не сработает. Это будет повторяться только до тех пор, пока не закончится меньший диапазон. В этом случае похоже, что вы хотите перебрать комбинацию циклов.

В другом случае вам просто нужен вложенный цикл.

 для i в x:
    для j в y:
        печать (стр (i) + " / " + строка (j))
 

дает вам

 1 / 4
1 / 5
1 / 6
2 / 4
2 / 5
...
 

Вы также можете сделать это как понимание списка.

 [str(i) + " / " + str(j) для i в диапазоне (x) для j в диапазоне (y)]
 

По какой причине нельзя использовать вложенный цикл for?

 для i в диапазоне (x):
   для j в диапазоне (y):
       #код, который использует i и j
 

5

 для (i,j) в [(i,j) для i в диапазоне (x) для j в диапазоне (y)]
 

должен сделать это.

3

Если у вас действительно есть итерация с фиксированным шагом по диапазону, вы можете сделать это одним из нескольких способов:

 для i в диапазоне (x):
  дж = я
  …
# или же
для i, j в перечислении (диапазон (x)):
  …
# или же
для i, j в ((i,i) для i в диапазоне (x)):
  …
 

Все вышеперечисленное эквивалентно для i, j в zip(range(x), range(y)) , если x <= y .

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

 для i в диапазоне (x):
  для я в диапазоне (у):
    …
 

Если у вас более двух итерируемых объектов, используйте itertools.product .

Наконец, если вы хотите итерацию с фиксированным шагом до x , а затем продолжить до y , вы должны решить, какие остальные 9Значения 0304 x должны быть.

 для i, j в itertools.zip_longest (диапазон (x), диапазон (y), fillvalue = float ('nan')):
  …
# или же
для я в диапазоне (мин (х, у)):
  дж = я
  …
для я в диапазоне (мин (х, у), макс (х, у)):
  j = поплавок ('нан')
  …
 

«Питон 3».

Добавьте 2 переменные с циклом for, используя zip и диапазон; Возврат списка.

Примечание. Работает только до окончания наименьшего диапазона.

 >>>a=[g+h для g,h в zip(диапазон(10), диапазон(10))]
>>>а
>>>[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
 

1

В вашем случае может быть проще использовать цикл while .

 t1 = [137, 42]
t2 = ["Привет", "мир"]
я = 0
j = 0
в то время как я < len (t1) и j < len (t2):
    напечатать t1[i], t2[j]
    я += 1
    j += 1
# 137 Привет
# 42 мир
 

В качестве предостережения: этот подход усекает длину вашего самого короткого списка.

2

Я думаю, вы ищете вложенные циклы.

Пример (на основе вашего редактирования):

 t1=[1,2,'Привет',(1,2),999,1.23]
t2=[1,'Привет',(1,2),999]
т3=[]
для it1, e1 в перечислении (t1):
    для it2, e2 в перечислении (t2):
        если е1==е2:
            t3.append((it1,it2,e1))
# t3=[(0, 0, 1), (2, 1, 'Привет'), (3, 2, (1, 2)), (4, 3, 999)]
 

Что можно свести к одному пониманию:

 [(it1,it2,e1) для it1, e1 в enumerate(t1) для it2, e2 в enumerate(t2), если e1==e2]
 

Но чтобы найти общие элементы, вы можете просто сделать:

 набор печати (t1) и набор (t2)
# set([(1, 2), 1, 'Привет', 999])
 

Если ваш список содержит нехешируемые объекты (например, другие списки, словари), используйте замороженный набор:

 из коллекций import Iterable
s1 = set (frozenset (e1), если isinstance (e1, Iterable), иначе e1 для e1 в t1)
s2 = set (frozenset (e2), если isinstance (e2, Iterable), иначе e2 для e2 в t2)
распечатать s1 и s2
 

Очень активный вопрос .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *