Идиома Python: если True делает True, если False делает один раз [дублировать]

Я думаю, что есть несколько типов потоковой передачи видео, которые могли бы изменить наш ответ здесь:

  • Прямая трансляция (подписчики смотрят, как происходит событие)
  • Стиль Youtube (после чего видео и конечные пользователи будут смотреть по их усмотрению)

Создав потоковое приложение стиля Periscope с использованием Firebase Storage и базы данных Firebase Realtime, я настоятельно рекомендую против этого - мы загрузили три вторых фрагмента и синхронизировать их через базу данных реального времени. Несмотря на то, что он работал (на удивление хорошо), на очень хорошем интернет-ресурсе было ~ 5 секунд латентности, и это также было не самым эффективным решением (в конце концов, вы загружаете и сохраняете это видео, а также не транскодируете) , Я рекомендую использовать некоторый стиль WebRTC, созданный для транспорта видео, и используя базу данных Realtime для передачи сигналов вдоль стороны потока.

С другой стороны, определенно возможно создать мобильные функции YT для Firebase. Трюк здесь будет транскодировать видео (используя что-то вроде Zencoder или Bitmovin, подробнее здесь: https://cloud.google.com/solutions/media/ ), чтобы вырезать загруженное видео в меньшие куски разных разрешений (и разные форматы, например, для iOS требуется HLS для потоковой передачи). Вы можете хранить информацию о куске в базе данных реального времени (имя фрагмента, доступные разрешения, количество фрагментов) и загружать упомянутые фрагменты из хранилища по мере продвижения видео.

588
задан Mogsdad 25 November 2015 в 05:42
поделиться

14 ответов

Я не уверен, что вы пытаетесь сделать. Вы можете реализовать цикл do-while следующим образом:

while True:
  stuff()
  if fail_condition:
    break

Или:

stuff()
while not fail_condition:
  stuff()

Что вы пытаетесь использовать цикл while, чтобы распечатать материал в список? Почему бы просто не использовать:

for i in l:
  print i
print "done"

Обновление:

Итак, у вас есть список строк? И вы хотите продолжать перебирать его? Как насчет:

for s in l: 
  while True: 
    stuff() 
    # use a "break" instead of s = i.next()

Кажется ли это чем-то близким к тому, что вы хотите? С вашим примером кода это будет:

for s in some_list:
  while True:
    if state is STATE_CODE:
      if "//" in s:
        tokens.add( TOKEN_COMMENT, s.split( "//" )[1] )
        state = STATE_COMMENT
      else :
        tokens.add( TOKEN_CODE, s )
    if state is STATE_COMMENT:
      if "//" in s:
        tokens.append( TOKEN_COMMENT, s.split( "//" )[1] )
        break # get next s
      else:
        state = STATE_CODE
        # re-evaluate same line
        # continues automatically
708
ответ дан jesugmz 18 August 2018 в 08:47
поделиться
  • 1
    Мне нужно создать конечный автомат. В конечной машине это нормальный случай для переоценки оператора CURRENT, поэтому мне нужно «продолжить» без повторения следующего элемента. Я не знаю, как это сделать в «for s in l:» iteration :( В цикле do-while «continue» будет переоценивать текущий элемент, итерацию в конце – grigoryvp 13 April 2009 в 07:41
  • 2
    Вы имеете в виду, что вам нужно отслеживать свое место в списке? Таким образом, когда вы возвращаете одно и то же состояние, вы можете подобрать место, где вы остановились? Дайте немного больше контекста. Похоже, вам может быть лучше использовать индекс в списке. – Tom 13 April 2009 в 07:48
  • 3
    добавлен пример псевдокода – grigoryvp 13 April 2009 в 08:32
  • 4
  • 5
    Жаль, что у python нет цикла do-while. Python СУХОЙ, а? – Kr0e 24 August 2013 в 09:53
  • 6
    Также см. PEP 315 для официальной позиции / обоснования: «Пользователям языка рекомендуется использовать форму while-True с внутренним if-break, когда цикл do-while был бы подходящим. & Quot; – dtk 15 August 2016 в 12:47

Если вы находитесь в сценарии, когда вы зацикливаете, пока ресурс недоступен или что-то подобное, что генерирует исключение, вы можете использовать что-то вроде

import time

while True:
    try:
       f = open('some/path', 'r')
    except IOError:
       print('File could not be read. Retrying in 5 seconds')   
       time.sleep(5)
    else:
       break
0
ответ дан Ajit 18 August 2018 в 08:47
поделиться

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

try:
  while True:
    if s:
      print s
    s = i.next()
except StopIteration:   
  pass

Я полагаю, что проблема с вашим кодом заключается в том, что поведение break внутри except не определен. Обычно break идет только на один уровень вверх, так, например, break внутри try переходит непосредственно к finally (если он существует) из try, но не из цикла.

Связанный PEP: http: // www.python.org/dev/peps/pep-3136 Связанный вопрос: Нарушение вложенных циклов

30
ответ дан Community 18 August 2018 в 08:47
поделиться
  • 1
    Это хорошая практика, хотя иметь только внутри оператора try то, что вы ожидаете, чтобы выбросить свое исключение, чтобы вы не поймали нежелательные исключения. – Paggas 2 November 2009 в 19:10
  • 2
  • 3
    @PiPeep: RTFM, поиск EAFP. – vartec 4 November 2010 в 10:35
  • 4
    @vartec Мои извинения, я новичок в Python – bgw 7 November 2010 в 20:47
  • 5
    @PiPeep: не проблема, просто имейте в виду, что то, что верно для некоторых языков, может быть неверным для других. Python оптимизирован для интенсивного использования исключений. – vartec 10 November 2010 в 17:30
  • 6
    break и continue отлично определены в любом предложении инструкции try / except / finally. Они просто игнорируют их и либо выходят из строя, либо переходят к следующей итерации содержащего while или для цикла, если это необходимо. В качестве компонентов циклов-конвейеров они имеют отношение только к операторам while и for и вызывают синтаксическую ошибку, если они запускаются в оператор класса или def перед достижением самого внутреннего цикла. Они игнорируют, если и с заявлениями. – ncoghlan 18 February 2011 в 07:41

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

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

first_pass = True
while first_pass or condition:
    first_pass = False
    do_stuff()
52
ответ дан evan54 18 August 2018 в 08:47
поделиться
  • 1
    Правильный ответ, я утверждаю. Кроме того, он избегает break , для безопасного использования в try / except blocks. – Zv_oDD 26 February 2016 в 20:41
  • 2
    Прекрасное, элегантное решение; запятнаны только неудачным смешением змеи и верблюжьего случая, но недостаточно для того, чтобы отговорить мою авантюру. – Apollys 25 April 2017 в 02:17
  • 3
    @Apollys Я изменил случай – evan54 1 July 2017 в 12:11

То, как я это сделал, выглядит следующим образом ...

condition = True
while condition:
     do_stuff()
     condition = (<something that evaluates to True or False>)

Мне кажется, что это упрощенное решение, я удивлен, что я не видел его здесь уже. Очевидно, это также можно инвертировать в

while not condition:

и т. Д.

0
ответ дан Gareth Lock 18 August 2018 в 08:47
поделиться

Посмотрите, помогает ли это:

Установите флаг внутри обработчика исключений и проверьте его перед работой над s.

flagBreak = false;
while True :

    if flagBreak : break

    if s :
        print s
    try :
        s = i.next()
    except StopIteration :
        flagBreak = true

print "done"
242
ответ дан martineau 18 August 2018 в 08:47
поделиться
  • 1
    Он не всегда добавляет дополнительную логическую переменную. Часто есть что-то (ы), которые уже существуют, чье состояние может быть проверено. – martineau 2 October 2012 в 18:32
  • 2
    Может быть упрощено с помощью while not flagBreak: и удаления if (flagBreak) : break. – martineau 2 October 2012 в 19:23
  • 3
    Причина, по которой мне больше всего нравится это решение, заключается в том, что он не добавляет еще одного условия, но это всего лишь один цикл, и если вы выберете хорошее имя для вспомогательной переменной, вся структура будет понятна. – Roberto 8 October 2013 в 22:04
  • 4
    ПРИМЕЧАНИЕ. Хотя это касается исходного вопроса, этот подход менее гибкий, чем при использовании break. В частности, если есть необходимая логика ПОСЛЕ test_loop_condition(), это не должно выполняться после завершения, оно должно быть завернуто в if condition:. BTW, condition неопределенна. Более наглядно: more или notDone. – ToolmakerSteve 15 December 2013 в 02:30
  • 5
    Я избегаю переменных с именем flag - я не могу определить, что означает значение True или False. Вместо этого используйте done или endOfIteration. Код превращается в while not done: .... – IceArdor 11 March 2014 в 22:03
  • 6
    @ToolmakerSteve Я не согласен. Я редко использую break в циклах, и когда я сталкиваюсь с ним в коде, который я поддерживаю, я обнаружил, что цикл, чаще всего, мог быть написан без него. Представленное решение - это IMO, способ clearest для представления do при построении в python. – nonsensickle 24 September 2015 в 23:48
  • 7
    В идеале условие будет называться чем-то описательным, например has_no_errors или end_reached (в этом случае цикл запустится while not end_reached – Josiah Yoder 28 September 2015 в 20:27
while condition is True: 
  stuff()
else:
  stuff()
7
ответ дан MuSheng 18 August 2018 в 08:47
поделиться
  • 1
    Еа. Это кажется значительно уродливым, чем использование перерыва. – mattdm 26 January 2012 в 16:42
  • 2
    Это умно, но для этого требуется stuff быть функцией или повторять тело кода. – Noctis Skytower 11 September 2012 в 21:08
  • 3
    Все, что необходимо, while condition:, потому что подразумевается is True. – martineau 2 October 2012 в 19:15
  • 4
    это не выполняется, если condition зависит от некоторой внутренней переменной stuff(), так как в этот момент эта переменная не определена. – yo' 25 February 2014 в 22:23
  • 5
    Не такая же логика, потому что на последней итерации при условии! = True: он вызывает код в последний раз. Где в качестве Do While сначала вызывает код, а затем проверяет состояние перед повторным запуском. Do While: выполнить блок один раз; затем проверьте и повторно запустите , этот ответ: проверить и повторно запустить; затем выполните блок кода один раз . Большая разница! – Zv_oDD 26 February 2016 в 20:34

Быстрый взломать:

def dowhile(func = None, condition = None):
    if not func or not condition:
        return
    else:
        func()
        while condition():
            func()

Использовать так:

>>> x = 10
>>> def f():
...     global x
...     x = x - 1
>>> def c():
        global x
        return x > 0
>>> dowhile(f, c)
>>> print x
0
6
ответ дан Naftuli Kay 18 August 2018 в 08:47
поделиться

Почему бы вам просто не сделать

for s in l :
    print s
print "done"

?

29
ответ дан Peter Mortensen 18 August 2018 в 08:47
поделиться
  • 1
    Мне нужно создать конечный автомат. В конечной машине это нормальный случай для переоценки оператора CURRENT, поэтому мне нужно «продолжить» без повторения следующего элемента. Я не знаю, как это сделать в «for s in l:» iteration :( В цикле do-while «continue» будет переоценивать текущий элемент, итерацию в конце. – grigoryvp 13 April 2009 в 07:26
  • 2
    то можете ли вы определить какой-то псевдокод для вашего конечного автомата, чтобы мы могли намекнуть вам на лучшее решение pythonic? Я не знаю много о государственных машинах (и, вероятно, не единственный), поэтому, если вы расскажете нам немного о своем алгоритме, нам будет легче помочь вам. – Martin 13 April 2009 в 07:48
  • 3
    добавлен пример псевдокода – grigoryvp 13 April 2009 в 08:29
  • 4
    Написание while True: stuff(); if not condition(): break - очень хорошая идея. Спасибо! – Noctis Skytower 11 September 2012 в 21:05
  • 5
    Для цикла не работает для таких вещей, как: a = fun (), в то время как == 'zxc': sleep (10) a = fun () – harry 19 September 2013 в 08:26
  • 6
    @ZeD, почему 1) уродливый? Это нормально, ИМХО – Sergey Lossev 8 January 2018 в 00:24

Вот более сумасшедшее решение другого шаблона - с помощью сопрограммы. Код по-прежнему очень похож, но с одним важным отличием; нет никаких условий выхода!

def coroutine(func):
    """Coroutine decorator

    Coroutines must be started, advanced to their first "yield" point,
    and this decorator does this automatically.
    """
    def startcr(*ar, **kw):
        cr = func(*ar, **kw)
        cr.next()
        return cr
    return startcr

@coroutine
def collector(storage):
    """Act as "sink" and collect all sent in @storage"""
    while True:
        storage.append((yield))

@coroutine      
def state_machine(sink):
    """ .send() new parts to be tokenized by the state machine,
    tokens are passed on to @sink
    """ 
    s = ""
    state = STATE_CODE
    while True: 
        if state is STATE_CODE :
            if "//" in s :
                sink.send((TOKEN_COMMENT, s.split( "//" )[1] ))
                state = STATE_COMMENT
            else :
                sink.send(( TOKEN_CODE, s ))
        if state is STATE_COMMENT :
            if "//" in s :
                sink.send(( TOKEN_COMMENT, s.split( "//" )[1] ))
            else
                state = STATE_CODE
                # re-evaluate same line
                continue
        s = (yield)

tokens = []
sm = state_machine(collector(tokens))
for piece in i:
    sm.send(piece)

Код выше собирает все токены в виде кортежей в tokens, и я полагаю, что нет никакой разницы между .append() и .add() в исходном коде.

16
ответ дан u0b34a0f6ae 18 August 2018 в 08:47
поделиться
244
ответ дан martineau 6 September 2018 в 21:44
поделиться
29
ответ дан Peter Mortensen 6 September 2018 в 21:44
поделиться
247
ответ дан martineau 30 October 2018 в 02:51
поделиться
30
ответ дан Peter Mortensen 30 October 2018 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: