iT邦幫忙

0

如何多次跳過Python 迴圈

  • 分享至 

  • xImage

我用Python嘗試判斷一個字串,假設字串為

query = "(test('abc') or tes('bcd') or te('cde')) and (test('efg') or tes('fgh') or te('ghi'))"

在字串中,我知道有test()、tes()、te()這些函式的存在,但不確定函式中的引數有哪些。
所以我想用for迴圈去跑這個字串,嘗試把字串結構化,可以用遞迴的方法處理它的樹狀結構。

for i in range(len(query)):
    match(query[i]):
        case('t'):
            if(query.find('test(',i) == i):
                #抓出函式中的引數進行處理
            elif(query.find('tes(',i) == i):
                #抓出函式中的引數進行處理
            elif(query.find('te(',i) == i):
                #抓出函式中的引數進行處理
        case('o'):
            if(query.find('or',i) == i):
                #這邊有個OR
        case('a'):
            if(query.find('and',i) == i):
                #這邊有個AND

我的問題是:假如程式在query[1]發現了"t",然後也用query.find('test(',1) == 1確認這個位置是test()函式,那我要如何在迴圈中跳過i=2~11的部分?
我試過在if的判斷式中加上函式的長度,例如:

for i in range(len(query)):
    match(query[i]):
        case('t'):
            if(query.find('test(',i) == i):
                i = i + 函式的長度

但迴圈還是會跑query[2]到query[11]的部分。
後來我在迴圈外加了一個skip的變數來決定continue的次數

skip = 0
for i in range(len(query)):
    if(skip > 0):
        skip = skip -1
        continue
    match(query[i]):
        case('t'):
            if(query.find('test(',i) == i):
                skip = 計算出函式的長度

這個方法是有效的。
但我想問,還有沒有更聰明的寫法?
請各位提供我改進程式的意見,感謝

看更多先前的討論...收起先前的討論...
hokou iT邦好手 1 級 ‧ 2022-10-06 09:35:17 檢舉
使用 break ??

https://medium.com/@chiayinchen/be290cd1f9d8
lsesroom iT邦新手 3 級 ‧ 2022-10-06 09:45:16 檢舉
break 會跳出整個迴圈吧,我需要把整個query判斷完
froce iT邦大師 1 級 ‧ 2022-10-06 09:50:57 檢舉
正則表示法。
Peter iT邦新手 4 級 ‧ 2022-10-12 13:52:32 檢舉
這應該是資料結構的問題,參考Stack實作就能解決了
https://openbookproject.net/thinkcs/python/english3e/stacks.html
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
海綿寶寶
iT邦大神 1 級 ‧ 2022-10-06 09:45:40

但我想問,還有沒有更聰明的寫法?

不用迴圈
改用Regular Expression

另外
你寫的程式裡
沒有遞迴

看更多先前的回應...收起先前的回應...
lsesroom iT邦新手 3 級 ‧ 2022-10-06 09:54:40 檢舉

我知道Regular Expression,但我不太懂怎麼用Regular Expression寫?能否麻煩簡單的舉個例子,感謝。
我的想法是先解析query,再跑遞迴處理樹狀結構的問題。我PO的這一部分只有解析query的部分,解析的結果會寫進陣列,然後用另一段程式來跑遞迴。

能否麻煩簡單的舉個例子

我回答裡的超連結就有例子

lsesroom iT邦新手 3 級 ‧ 2022-10-06 10:35:06 檢舉

我大概的想法是這樣:
可以用re把函式的位置跟引數的內容抓出來,
然後用迴圈判斷括號來處理樹狀的架構
是這樣嗎?

所以你想做的是「處理 query 的敍述並求得結果」
而你問的只是「如何跳出迴圈」

你想做的事情叫做 Expression Evaluation
簡單版的可以看比較常見的這篇
完整版的(也是你需要看的)要參考這篇

如果你不想看前人的理論
要自己從無到有刻出一套做法
我也只有祝你好運了

froce iT邦大師 1 級 ‧ 2022-10-06 11:18:54 檢舉

https://docs.python.org/zh-tw/3/howto/regex.html

tes?t?\((?P<params>[\w\'\"\, ]*)\)

直接給你正則表示法,自己去用 named group去把參數取出來再分割。
程式碼大概沒幾行就可以了。關鍵字和關鍵的表示法都給了,剩下你自己研究。

這種東西不用正則寫會搞死自己。

lsesroom iT邦新手 3 級 ‧ 2022-10-06 14:09:08 檢舉

可能我問題沒有描述得很明確,因為在這個邏輯判斷的樹裡面還要做其他的處理,而我沒有把全部的程式內容都完整打出來。
上面網友的回覆也對我要處理的一些問題有所幫助,感謝

froce iT邦大師 1 級 ‧ 2022-10-06 14:29:46 檢舉

你給完整的,我們給的答案大概一樣也是正則表示法。
你這東西就是用正則做最快最簡單,加上python的正則有支援named group,你大可提取出你所需要的資訊,後面再去處理。

0
tryit
iT邦研究生 4 級 ‧ 2022-10-06 14:57:46

你給的東西,好像什麼程式考題喔。
老實說這東西用re模組真的比較方便啦,但如果你真的不想用的話為啥不嘗試用while+切片處理呢

i = 0
while i < (len(query)):
    match(query[i]):
        case('t'):
            if(query.find('test(',i) == i):
                #抓出函式中的引數進行處理
            elif(query.find('tes(',i) == i):
                #抓出函式中的引數進行處理
            elif(query.find('te(',i) == i):
                #抓出函式中的引數進行處理
            query = query[i:]
            i=-1
        case('o'):
            if(query.find('or',i) == i):
                #這邊有個OR
            query = query[i:]
            i=-1
        case('a'):
            if(query.find('and',i) == i):
                #這邊有個AND
            query = query[i:]
            i=-1
       
   i+=1

但老實說,我不管怎麼想都覺得會出問題啦,建議別用,乖乖用re得永生

2
一級屠豬士
iT邦大師 1 級 ‧ 2022-10-06 21:18:40

Python 有 label 可以應用.

https://peps.python.org/pep-3136/

libcst 可以試試看

https://libcst.readthedocs.io/en/latest/index.html

import libcst

q1 = "(test('abc') or tes('bcd') or te('cde')) and (test('efg') or tes('fgh') or te('ghi'))"

libcst.parse_expression(q1)
BooleanOperation(
    left=BooleanOperation(
        left=BooleanOperation(
            left=Call(
                func=Name(
                    value='test',
                    lpar=[],
                    rpar=[],
                ),
                args=[
                    Arg(
                        value=SimpleString(
                            value="'abc'",
                            lpar=[],
                            rpar=[],
                        ),
                        keyword=None,
                        equal=MaybeSentinel.DEFAULT,
                        comma=MaybeSentinel.DEFAULT,
                        star='',
                        whitespace_after_star=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_arg=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ],
                lpar=[],
                rpar=[],
                whitespace_after_func=SimpleWhitespace(
                    value='',
                ),
                whitespace_before_args=SimpleWhitespace(
                    value='',
                ),
            ),
            operator=Or(
                whitespace_before=SimpleWhitespace(
                    value=' ',
                ),
                whitespace_after=SimpleWhitespace(
                    value=' ',
                ),
            ),
            right=Call(
                func=Name(
                    value='tes',
                    lpar=[],
                    rpar=[],
                ),
                args=[
                    Arg(
                        value=SimpleString(
                            value="'bcd'",
                            lpar=[],
                            rpar=[],
                        ),
                        keyword=None,
                        equal=MaybeSentinel.DEFAULT,
                        comma=MaybeSentinel.DEFAULT,
                        star='',
                        whitespace_after_star=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_arg=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ],
                lpar=[],
                rpar=[],
                whitespace_after_func=SimpleWhitespace(
                    value='',
                ),
                whitespace_before_args=SimpleWhitespace(
                    value='',
                ),
            ),
            lpar=[],
            rpar=[],
        ),
        operator=Or(
            whitespace_before=SimpleWhitespace(
                value=' ',
            ),
            whitespace_after=SimpleWhitespace(
                value=' ',
            ),
        ),
        right=Call(
            func=Name(
                value='te',
                lpar=[],
                rpar=[],
            ),
            args=[
                Arg(
                    value=SimpleString(
                        value="'cde'",
                        lpar=[],
                        rpar=[],
                    ),
                    keyword=None,
                    equal=MaybeSentinel.DEFAULT,
                    comma=MaybeSentinel.DEFAULT,
                    star='',
                    whitespace_after_star=SimpleWhitespace(
                        value='',
                    ),
                    whitespace_after_arg=SimpleWhitespace(
                        value='',
                    ),
                ),
            ],
            lpar=[],
            rpar=[],
            whitespace_after_func=SimpleWhitespace(
                value='',
            ),
            whitespace_before_args=SimpleWhitespace(
                value='',
            ),
        ),
        lpar=[
            LeftParen(
                whitespace_after=SimpleWhitespace(
                    value='',
                ),
            ),
        ],
        rpar=[
            RightParen(
                whitespace_before=SimpleWhitespace(
                    value='',
                ),
            ),
        ],
    ),
    operator=And(
        whitespace_before=SimpleWhitespace(
            value=' ',
        ),
        whitespace_after=SimpleWhitespace(
            value=' ',
        ),
    ),
    right=BooleanOperation(
        left=BooleanOperation(
            left=Call(
                func=Name(
                    value='test',
                    lpar=[],
                    rpar=[],
                ),
                args=[
                    Arg(
                        value=SimpleString(
                            value="'efg'",
                            lpar=[],
                            rpar=[],
                        ),
                        keyword=None,
                        equal=MaybeSentinel.DEFAULT,
                        comma=MaybeSentinel.DEFAULT,
                        star='',
                        whitespace_after_star=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_arg=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ],
                lpar=[],
                rpar=[],
                whitespace_after_func=SimpleWhitespace(
                    value='',
                ),
                whitespace_before_args=SimpleWhitespace(
                    value='',
                ),
            ),
            operator=Or(
                whitespace_before=SimpleWhitespace(
                    value=' ',
                ),
                whitespace_after=SimpleWhitespace(
                    value=' ',
                ),
            ),
            right=Call(
                func=Name(
                    value='tes',
                    lpar=[],
                    rpar=[],
                ),
                args=[
                    Arg(
                        value=SimpleString(
                            value="'fgh'",
                            lpar=[],
                            rpar=[],
                        ),
                        keyword=None,
                        equal=MaybeSentinel.DEFAULT,
                        comma=MaybeSentinel.DEFAULT,
                        star='',
                        whitespace_after_star=SimpleWhitespace(
                            value='',
                        ),
                        whitespace_after_arg=SimpleWhitespace(
                            value='',
                        ),
                    ),
                ],
                lpar=[],
                rpar=[],
                whitespace_after_func=SimpleWhitespace(
                    value='',
                ),
                whitespace_before_args=SimpleWhitespace(
                    value='',
                ),
            ),
            lpar=[],
            rpar=[],
        ),
        operator=Or(
            whitespace_before=SimpleWhitespace(
                value=' ',
            ),
            whitespace_after=SimpleWhitespace(
                value=' ',
            ),
        ),
        right=Call(
            func=Name(
                value='te',
                lpar=[],
                rpar=[],
            ),
            args=[
                Arg(
                    value=SimpleString(
                        value="'ghi'",
                        lpar=[],
                        rpar=[],
                    ),
                    keyword=None,
                    equal=MaybeSentinel.DEFAULT,
                    comma=MaybeSentinel.DEFAULT,
                    star='',
                    whitespace_after_star=SimpleWhitespace(
                        value='',
                    ),
                    whitespace_after_arg=SimpleWhitespace(
                        value='',
                    ),
                ),
            ],
            lpar=[],
            rpar=[],
            whitespace_after_func=SimpleWhitespace(
                value='',
            ),
            whitespace_before_args=SimpleWhitespace(
                value='',
            ),
        ),
        lpar=[
            LeftParen(
                whitespace_after=SimpleWhitespace(
                    value='',
                ),
            ),
        ],
        rpar=[
            RightParen(
                whitespace_before=SimpleWhitespace(
                    value='',
                ),
            ),
        ],
    ),
    lpar=[],
    rpar=[],
)

今天才知道有這樣的library
真是長知識,賺到了
/images/emoticon/emoticon41.gif

obarisk iT邦研究生 2 級 ‧ 2022-10-07 09:49:32 檢舉

ast 應該也可以解

我要發表回答

立即登入回答