• Python progr Удивительное дело в питоне — никакой демократии, сплошная диктатура!
    ```
    for i in range(0,10):
    print i
    i=5
    ```
    Результат выполнения:
    ```
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ```
    Т.е. переменную счётчика цикла нельзя менять! Причём никакой ошибки не выдаётся, полное ощущение, что всё работает, но нет.
    После анархии в перле и C это выглядит дико
    ♡ recommended by @kitt, @Strephil

Replies (37)

  • @Shura, в смысле? О_О

    ты же присваиваешь i после того как вывел, и до того как в новой итерации ей присвоится новое значение. Поменяй местами последние строчки и будет тебе 55555555555555555555
  • @Renha, будет, но цикл от этого бесконечным не становится. Т.е. логично, потому что range имеет внутренний счётчик и на каждый цикл его передаёт в i. Т.е. в циле for нельзя поменять счётчик цикла. Т.е. for не числовой, а итерационный. Это немного непривычно.
  • @Shura, Потому что здесь нет никакого счётчика цикла. Ты просто идёшь по списку, который вернул range.
  • @kapsh, да. for не позволяет делать нумерованные счётчики. Только while, но там это надо делать вручную, и выглядит это костыльно.
    К этому надо просто привыкнуть
  • @Shura, Нет, привыкнуть надо не использовать счётчики. Покажи код, в котором они тебе нужны — возможно, я более питонический способ подсказать смогу.
  • @kapsh, сравнение элементов массива между собой
  • @Shura, просто сравнение или с какой-то целью?
  • @oxpa, с какой-то целью. Например если результат сравнения удовлетворяет, то положить элемент в другой массив
    Сейчас использую трюк с enumerate, который выдаёт индекс элемента, а дальше по-старинке — двумя вложенными циклами i,j
  • @Shura, можно делать как
    i = a[0]
    for j in a[1:]:
    if j<i:
    dosmth(j)
    i=j
  • @Shura, ещё можно с извращениями. Как-нибудь:
    b = [ i for i in a if any([j<i for i in a]) ]Но за такое будут пороть, вероятно
  • @Shura, A= [1,2,3]
    B= [5,4,3]
    C= []
    for a,b in zip(A,B):
    _if a == b:
    __C.append(a)
  • @oxpa, тут вообще голову сломаешь. При этом, если правильно понимаю, ломается массив a, потому что всё время слайсится.
  • @Renha, у тебя A и B разные массивы. По условиям — один
  • @Shura, нет, "а" остаётся нетронутым. слайсы не изменяют исходный массив
  • @Shura, a, миспрочитал
  • @oxpa, Сейчас у меня вот так:
    ```
    while i < len(_lines)-1:
    l1=_lines[i]
    flag=0
    for j in range(i+1,len(_lines)):
    do_smth(_lines[j])
    i+=1
    ```

    Как и в любом другом языке. Просто вместо while нормальный, нумерованный цикл for смотрелся бы гармоничнее
  • @oxpa, со слайсами надо попробовать, выглядит лучше моего франкенштейна
  • @Shura, у тебя же не используется l1...
  • @oxpa, на самом деле используется, просто покоцал для лучшей читаемости, когда сюда вставлял
  • @Shura, давно бы показал как есть, мы бы предложили pythonic way для того же самого
  • @oxpa, ну или на пасту и в приват куда-нибудь, если светить не хочется
  • @oxpa, там ничего секретного, просто очень большая простыня. Есть массив с линиями. Линии сравниваются между собой и если их концы рядом друг с другом и угол между линиями не большой, то линии объединяются в одну. Поэтому и нужно сравнение элементов одного массива между собой.

    Да собственно, пост был создан не с просьбой о помощи, а просто как заметка о питоне
  • @oxpa, вот такое красиво, я бы применил, если бы функция сравнения элементов влезала в одну строчку
  • @Shura, да можно обернуть всё в функцию и подсунуть, почему нет...
  • @Shura, и ещё я не уверен, что получится вытащить переменную из второго comprehension. Но тогда можно j вытащить куда-нибудь выше
  • @Shura, Не выходит со слайсами.
    ```
    a=range(10,20)
    for i in a:
    print "i=",i
    for j in a[1:]:
    #if j<i:
    print "\tj=",j
    ```
    j всё время гоняется с 11 по 19, а должен на каждом цикле увеличивать стартовый индекс на единичку. Т.е. в слайс так и так индекс загонять надо, а для этого он должен быть.
  • @Shura,
    from itertools import product
    a=range(10,20)
    for i in itertools.product(a, repeat=2):
    print i;

    В i оказывается тапл, который можно передать куда-нибудь как два аргумента.
  • @oxpa, тьфу ты! я там перепутал и с модулем вызываю itertools.product, но понятно, наверно
    Ещё есть permutations, cominations и всякое такое.
    docs.python.org
    сами itertools у тебя наверняка есть (только если не совсем старьё)
  • @oxpa, хе-хе
    Traceback (most recent call last):
    File "test.py", line 10, in <module>
    for i in itertools.product(a, repeat=2):
    NameError: name 'itertools' is not defined
  • @Shura, это я коряво импорт написал, ну =)
  • @oxpa, справился, сейчас поковыряю. Спасибо
  • @Shura, In [15]: arr1 = [1, 0, 3, 4, 0]

    In [16]: arr2 = [1, 0, 0, 4, 0]

    In [17]: [a for a, b in zip(arr1, arr2) if a == b]
    Out[17]: [1, 0, 4, 0]

    Это если я правильно понял твою задачу. Все каменты лень читать.
  • @kapsh, Прочитал, похоже что не понял.
  • @oxpa, вот как раз мой случай
    for i in itertools.combinations(a,2):
    Спасибо, избавлюсь от индексов, while и ручного инкремента счётчика :)
  • @Shura, в jabber'е есть прекрасный python@c.j.r. Я там не сижу, но там всегда подскажут даже сложные штуки
  • @Shura, Я бы срал кирпичами, если бы этот код вел себя так, как ты хочешь.
  • @Shura, Это потому что for-in — это не цикл со счётчиком, это обход итератора. Причем там ещё такая магия, что по сути неявно получается итератор от переданного объекта, то есть по факту реальный код твоего цикла будет выглядеть следующим образом:
    iterator = iter(range(10))
    while True:
    ____try:
    ________print iterator.next() # в Python 3 будет "next(iterator)"
    ____except StopIteration:
    ________break