Skip to main content
Code fence and prettify hint
Source Link
Toby Speight
  • 88.4k
  • 14
  • 104
  • 327
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
```
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
```
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
added 651 characters in body
Source Link

Edit:

Here's a quick performance comparison against flat as given by @Reinderien:

def flat(t):
    if isinstance(t, tuple):
        for x in t:
            yield from flat(x)
    else:
        yield t
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
```

Edit:

Here's a quick performance comparison against flat as given by @Reinderien:

def flat(t):
    if isinstance(t, tuple):
        for x in t:
            yield from flat(x)
    else:
        yield t
In [2]: def f(x0,x1,x2,x3,x4,x5,x6,x7):
   ...:     return x0+x1+x2+x3+x4+x5+x6+x7
   ...: 

In [3]: %timeit f(*flat(((10,20,30),(40,50),(60,70,80))))
2.06 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [4]: %timeit f(*flatten_tuple(((10,20,30),(40,50),(60,70,80)), ((3,),(2,),(3,))))
383 ns ± 17.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
```
Became Hot Network Question
added 2 characters in body
Source Link
def flatten_tuple(data, structure, cache={}):
    if not (unpacker := cache.get(structure)):

        def get_unstruct(structure, n_vars):
            if isinstance(structure, int):
                if structure == 0:
                    return "*x""*x%d" +% n_vars, n_vars + 1
                if structure == -1:
                    return "_", n_vars
                new_n_vars = n_vars + structure
                ret = ",".join("x%d" % i for i in range(n_vars, new_n_vars))
                n_vars = new_n_vars
                return ret, new_n_vars
            assert isinstance(structure, tuple)
            unstruct_code = "("
            for x in structure:
                unstruct_code_one, n_vars = get_unstruct(x, n_vars)
                unstruct_code += unstruct_code_one + ","
            return unstruct_code + ")", n_vars

        unstruct_code, n_vars = get_unstruct(structure, 0)
        local_dict = {}
        exec(
            compile("def unpacker(data):\n %s = data\n return x%s" %
                    (unstruct_code, ",x".join(map(str, range(n_vars)))),
                    "",
                    "exec",
                    dont_inherit=True), {}, local_dict)
        unpacker = local_dict["unpacker"]
    cache[structure] = unpacker
    return unpacker(data)
def flatten_tuple(data, structure, cache={}):
    if not (unpacker := cache.get(structure)):

        def get_unstruct(structure, n_vars):
            if isinstance(structure, int):
                if structure == 0:
                    return "*x" + n_vars, n_vars + 1
                if structure == -1:
                    return "_", n_vars
                new_n_vars = n_vars + structure
                ret = ",".join("x%d" % i for i in range(n_vars, new_n_vars))
                n_vars = new_n_vars
                return ret, new_n_vars
            assert isinstance(structure, tuple)
            unstruct_code = "("
            for x in structure:
                unstruct_code_one, n_vars = get_unstruct(x, n_vars)
                unstruct_code += unstruct_code_one + ","
            return unstruct_code + ")", n_vars

        unstruct_code, n_vars = get_unstruct(structure, 0)
        local_dict = {}
        exec(
            compile("def unpacker(data):\n %s = data\n return x%s" %
                    (unstruct_code, ",x".join(map(str, range(n_vars)))),
                    "",
                    "exec",
                    dont_inherit=True), {}, local_dict)
        unpacker = local_dict["unpacker"]
    cache[structure] = unpacker
    return unpacker(data)
def flatten_tuple(data, structure, cache={}):
    if not (unpacker := cache.get(structure)):

        def get_unstruct(structure, n_vars):
            if isinstance(structure, int):
                if structure == 0:
                    return "*x%d" % n_vars, n_vars + 1
                if structure == -1:
                    return "_", n_vars
                new_n_vars = n_vars + structure
                ret = ",".join("x%d" % i for i in range(n_vars, new_n_vars))
                n_vars = new_n_vars
                return ret, new_n_vars
            assert isinstance(structure, tuple)
            unstruct_code = "("
            for x in structure:
                unstruct_code_one, n_vars = get_unstruct(x, n_vars)
                unstruct_code += unstruct_code_one + ","
            return unstruct_code + ")", n_vars

        unstruct_code, n_vars = get_unstruct(structure, 0)
        local_dict = {}
        exec(
            compile("def unpacker(data):\n %s = data\n return x%s" %
                    (unstruct_code, ",x".join(map(str, range(n_vars)))),
                    "",
                    "exec",
                    dont_inherit=True), {}, local_dict)
        unpacker = local_dict["unpacker"]
    cache[structure] = unpacker
    return unpacker(data)
Source Link
Loading