Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

多次元リストのフラット化をwhile/再帰を使わずにやってみた

More than 1 year has passed since last update.

リストのフラット化と言えば、

def flat(i):
    loop = True
    while loop:
        o = []
        loop = False
        for i in i:
            if type(i) in [list,tuple]:
                for i in i:
                    o.append(i)
                loop = True
            else:
                o.append(i)
        i = o
    return i

cc0

のように繰り返して展開することがほとんどでしょう。というかこれで事足ります。

何で書いちゃったんでしょうか、私は文字列にしたらループ抑制できるのでは?と考えました。
そのコードがコチラ

def element_act(element,d) -> any:
    """
    elementはlist(str) str:コレクション型には対応していません。
    """
    if element[0] in "'\"" and element[-1] in "'\"":
        return "".join(element[1:-1])
    elif all([True if i in "0123456789" else False for i in element]):
        return int("".join(element))
    elif all([True if i in "0123456789." else False for i in element]) and element.count(".") == 1:
        return float("".join(element))
    else:
        dic = {"None":None,"False":False,"True":True}
        dic.update(d)
        if "".join(element) in dic.keys():
            return dic["".join(element)]
        return globals()["".join(element)]
def flat(line,d={}) -> list:
    """
    第一引数はリスト、タプル、文字列に対応しています。
    ただし、文字列の場合、文字列内で文字列を表現する際のエスケープシーケンスに注意してください。\n
    第二引数のdは第一引数(が文字列の場合)に登場する変数の代入になります。\n
    グローバル変数は代入しなくても参照できますが、\n
    ローカル変数については指定しないと参照できません。\n
    ex)
    ((1,2),("5,6",a,("\\\\"\\\\'\\\\' \\\\\\\\  "),45)) -> '((1,2),("5,6",a,("\\\\\\\\"\\\\\\\\\\'\\\\\\\\\\' \\\\\\\\\\\\\\\\  "),45))'
    """
    line = [i for i in (repr(line) if type(line)==list or type(line)==tuple else line)]
    str_ = False
    element = []
    output_list = []
    for i in range(len(line)):
        Esc = line[i-1] == "\\"
        i = line[i]
        if str_ != False or not i in [" ",",","[","]","(",")"]:
            if i == "\\" and not Esc:
                continue
            else:
                element.append(i)
        if i == "," and str_ == False:
            output_list.append(element_act(element,d))
            element = []
        if str_ == False and i in "'\"":
            str_ = i
        elif str_ == i and not Esc:
            str_ = False
    output_list.append(element_act(element,d))
    return output_list
if __name__ == "__main__":
    a = "a\'"
    def test():
        a = "\"b\\\'\""
        print(flat(  f'((1,2),("5,6",{a},("\\"\\\'\\\' \\\\  "),45))'  ))
        print(flat(  '((1,2),("5,6",None,ab,("\\"\\\'\\\' \\\\  "),45))'  ,{"ab":"b'"}))
    test()
    print(flat(  ((1,2),("5,6",a,("\"\'\' \\  "),45))  ))
    print(flat(  '((1,2),("5,6",a,("\\"\\\'\\\' \\\\  "),45,5.5))'  ,{}))

cc0

変わらんのでは…?
検証は面倒というか分からないのでやってません。では、しーゆーあげいん

New_enpitsu_15
よろしくおねがいします。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away