How to unpack list created by map(lambda) inside a tuple?

Question:

I have a list of strings of which I want to have all the possible cased versions of a few string (e.g. ‘yes’ -> ‘yes’, ‘Yes’, ‘YES’, etc.). I’m using a map(lambda) construction, but I can’t get the strings that are returned to be **not ** in a nested list like that. How do I do this?

>> (
some_other_objects,
*list((map(lambda s: list(map(''.join, itertools.product(*zip(s.upper(), s.lower())))), ['no', 'maybe'])))
)

# actual result:
(
some_other_objects,
['no', 'No', 'NO', 'nO', ...],
['Maybe', 'maybe', 'MAYBE', ...]
)

# desired result:
(
some_other_objects,
'no', 'No', 'NO', 'nO', ..., 
'Maybe', 'maybe', 'MAYBE', ...
)

Thank you in advance!!

Tried a lot with unpacking and listing already but nothing seems to work..

Asked By: Max

||

Answers:

Unpack an itertools.chain:

x = (
    'foo',
    *itertools.chain(*(map(lambda s: list(map(''.join, itertools.product(*zip(s.upper(), s.lower())))), ['no', 'maybe'])))
)
print(x)

This outputs

('foo', 'NO', 'No', 'nO', 'no', 'MAYBE', 'MAYBe', 'MAYbE', 'MAYbe', 'MAyBE', 'MAyBe', 'MAybE', 'MAybe', 'MaYBE', 'MaYBe', 'MaYbE', 'MaYbe', 'MayBE', 'MayBe', 'MaybE', 'Maybe', ...)

Further, I’d probably use a generator expression instead of map/lambda:

import itertools

x = (
    "foo",
    *itertools.chain(
        *(
            ("".join(c) for c in itertools.product(*zip(s.upper(), s.lower())))
            for s in ["no", "maybe"]
        )
    ),
)

print(x)
Answered By: AKX

Turned AKX’s answer into a function, and eliminated the bug he/she later mentioned:

def string_all_cases(*strings):
    """ Returns given string(s) in all possible combinations of 
    lowercase and uppercase.
    
    :param s: {str or tup(str)} Input string(s).
    :returns: {list[str]} A list of all different cased possibilities of 
    all the input strings.
    
    :example:
    
    >> print(string_all_cases('foo'))
    ['FOO', 'FOo', 'FoO', 'Foo', 'fOO', 'fOo', 'foO', 'foo']
    
    >> print(string_all_cases('foo', 'bar'))
    ['FOO', 'FOo', 'FoO', 'Foo', 'fOO', 'fOo', 'foO', 'foo', 'BAR', 'BAr', 
     'BaR', 'Bar', 'bAR', 'bAr', 'baR', 'bar']
    """
    for string in strings: assert type(string) is str
    
    s = [string for string in strings]
    
    return list(itertools.chain(
                *(
                    ("".join(c) for c in itertools.product(*zip(si.upper(), si.lower())))
                    for si in s)
                ),
            )
Answered By: Max
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.