0

We seek a function ba such that ba returns strings. Specific examples of the desired behavior of ba are shown below:

+------------------+--------+
|      INPUT       |  OUT   |
+------------------+--------+
| 0                | "0"    |
| [[0, 1], 2, 3]   | "0123" |
| [0, 1, 2, 3]     | "0123" |
| [0, [1, [2, 3]]] | "0123" |
+------------------+--------+

Consider the following function:

def a(x):
    if hasattr(x, '__iter__'):
        return map(a, x)
    return x

EDIT!

Note that the following is an infinite loop:

it = "python"
while hasattr(it, '__iter__'):
    it = iter(it)

This is because "p"[0][0][0][0][0][0][0]...[0] == "p"

Thus, we really want something like:

def a(xparent):
    try:
        r = xparent
        if hasattr(xx, '__iter__'):
            iparent = iter(xparent)
            if iparent != xparent:
                r = map(a, xparent)
    finally:
        return r

Assume that you're not allowed to change a very much. If ba == lambda x: b(a(x)), the questions is, what would work for function b?

The following candidates don't work:

b = lambda x: ''.join(map(str, x))
b = lambda x: str(map(str, x))

Below is some code I created for testing/debugging potential candidates for function b:

#     YOU CAN IGNORE MOST OF THE BEGINNING OF THE FOLLOWING SCRIPT
#                              _  _       _
#                             | || |     | |
#      ___   ___  _ __   ___  | || |   __| |  ___  __      __ _ __
#     / __| / __|| '__| / _ \ | || |  / _` | / _ \ \ \ /\ / /| '_ \
#     \__ \| (__ | |   | (_) || || | | (_| || (_) | \ V  V / | | | |
#     |___/ \___||_|    \___/ |_||_|  \__,_| \___/   \_/\_/  |_| |_|
#
#
#

if True:
    # `stderr` is printed out-of-order with `stdout`.
    #
    # I'm tired of exceptions printed to `stderr`
    # messing up the print statements
    #
    import sys
    _print  = lambda *args, file=sys.stderr, end="\n",:\
        file.write(' '.join(map(lambda arg: str(arg).strip(" "), args)) + end)
    print = _print

##############################################################

import inspect
import io

def e(mahp):
    out_frm = inspect.currentframe().f_back
    try:
        outout = eval(mahp, out_frm.f_globals, out_frm.f_locals)
    except BaseException as exc:
        with io.StringIO() as out:
            print(type(exc), exc, file=out)
            outout = out.getvalue()
    finally:
        try:
            return outout
        except UnboundLocalError:
            raise ValueError(''.join((x for x in (
                "except block failed to assighn to `outout`"
                "most likely "
            ))))



############################################################
#          _                                           _  _  _
#         | |                                         | || |(_)
#     ___ | |_   ___   _ __    ___   ___  _ __   ___  | || | _  _ __    __ _
#    / __|| __| / _ \ | '_ \  / __| / __|| '__| / _ \ | || || || '_ \  / _` |
#    \__ \| |_ | (_) || |_) | \__ \| (__ | |   | (_) || || || || | | || (_| |
#    |___/ \__| \___/ | .__/  |___/ \___||_|    \___/ |_||_||_||_| |_| \__, |
#                     | |                                               __/ |
#                     |_|                                              |___/

import copy

# def a(xparent):
#    try:
#        r = xparent
#        if hasattr(xparent, '__iter__'):
#            iparent = iter(xparent)
#            if iparent != xparent:
#                r = map(a, xparent)
#    finally:
#        pass
#    return r

def a(x):
    if hasattr(x, '__iter__'):
        return map(a, x)
    return x

Lneg = "01234"
L0 = 0
L1 = [[0, 1], 2, 3]
L2 = [0, 1, 2, 3]
L3 = [0, [1, [2, 3]]]

Ls = [Lneg, L0, L1, L2, L3]

def observe_one(candidate):
    candidate = str(candidate)
    print(candidate, end="\n    ")
    print(e(candidate))
    return

def observe_all(mahp):
    if True:
        # `mahp` is an iterator. As such, it will be empty once
        # traversed. Use `deepcopy` to test `mahp` multiple times
        print(30*"#")
        print("L == ", end="\n    ")
        print(L)
        print()
        observe_one("''.join(map(str, copy.deepcopy(mahp)")
        print()
        observe_one("str(map(str, copy.deepcopy(mahp)))")
        print(30 * "#")

for L in Ls:
    try:
        mahp = a(L)
        observe_all(mahp)
    finally:
        pass
Community
  • 1
  • 1
Toothpick Anemone
  • 4,290
  • 2
  • 20
  • 42
  • 1
    If we can ignore it, remove it from the question. – chepner Oct 24 '19 at 23:39
  • I don't understand `a()`. It doesn't do anything useful. It just turns lists into annoying ``s. If you change it to `return list(map(a, x))` then it's basically an identity function. – John Kugelman Oct 24 '19 at 23:41
  • Are you asking how to flatten an arbitrarily nested iterable? – juanpa.arrivillaga Oct 24 '19 at 23:42
  • 2
    Is this an academic exercise, a homework problem? If not, it's a duplicate. See: [Flatten an irregular list of lists](https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists). – John Kugelman Oct 24 '19 at 23:43
  • @juanpa.arrivillaga Almost. There are times when we want the maps (or some kind of iterator), and not a string. That is, function `a` is useful by itself. – Toothpick Anemone Oct 25 '19 at 01:09
  • @ToothpickAnemone as an aside, I reorganized the code a little bit with a recent edit into something more sane – juanpa.arrivillaga Oct 25 '19 at 03:17
  • @chepner If you removed the code I say to ignore, the code which I say not to ignore would not run. The ignorable code is some code for pretty printing. – Toothpick Anemone Oct 25 '19 at 12:35

0 Answers0