-1

I want to be able to convert some strings to lists of characters, and vice versa. However, all spaces within the strings should be represented by an empty string element in the corresponding list. For example:

typed_words = ['T', "y", "p", "e", "", "t", "h", "i", "s"]  
target_text = "Type this"

I've tried using the join method to convert the list into a string, but since there is an empty element in the list, it creates a string with no spaces.

How do I allow for the special case of ''/' ' amidst the rest of the characters?

CrazyChucky
  • 3,263
  • 4
  • 11
  • 25
Jack Ciafardo
  • 31
  • 1
  • 8
  • If there's an empty string `""` element in `typed_words`, is that *always* going to correspond to a singular whitespace in `target_text`? If so, why not just do a quick list comprehension-type operation to replace it when joining? – esqew May 20 '22 at 00:39
  • Thats why I was asking... – Jack Ciafardo May 20 '22 at 00:50
  • But esqew is asking because it would help to clarify your question. – CrazyChucky May 20 '22 at 12:11
  • (Specifically, you've shown one example, but they are asking if spaces always behave that way in the general case.) – CrazyChucky May 20 '22 at 12:17

3 Answers3

0

First of all, if one ignores the space-to-empty-string issue, converting a list of characters to a string and back again is as simple as:

# Converting the list to a string:
total_string = ''.join(list_of_characters)
# Converting the string to a list:
list_of_characters = list(total_string)

In your case, you need the extra step of converting between spaces and empty strings, which you can accomplish with a list comprehension.

For instance, here's a list comprehension (split onto multiple lines for extra clarity) that reproduces a list faithfully, except with empty string elements replaced with spaces:

[
    ' ' if char == '' else char
    for char in list_of_characters
]

So your final conversions would look like this:

# Converting the list to a string:
total_string = ''.join([' ' if char == '' else char for char in list_of_characters])
# Converting the string to a list:
list_of_characters = ['' if char == ' ' else char for char in total_string]

Note that one can iterate over a string just like iterating over a list, which is why that final comprehension can simply iterate over total_string rather than having to do list(total_string).


P.S. An empty string ('') evaluates to False in boolean contexts, so you could make use of the or operator's short-circuiting behavior to use this shorter (though arguably less immediately legible) version:

# Converting the list to a string:
total_string = ''.join([char or ' ' for char in list_of_characters])
CrazyChucky
  • 3,263
  • 4
  • 11
  • 25
-1

For making a list, you need to iterate every char and append it to a list.

def strToList(s):
    l = []

    for c in s:
        l.append(c)
    
    return l

For doing the inverse operation, python allows using the += operator on strings:

def listToStr(l):
    s = ""

    for c in l:
        s += str(c)

    return s
Easy
  • 41
  • 2
  • 5
  • Welcome to Stack Overflow! I would recommend looking into [`str.join`](https://docs.python.org/3/library/stdtypes.html#str.join), which is generally the more idiomatic (and faster) way to [combine a bunch of strings](https://waymoot.org/home/python_string/) in Python. – CrazyChucky May 20 '22 at 12:36
  • (Also keep in mind, your answer doesn't address the asker's issue of converting between spaces and empty strings.) – CrazyChucky May 20 '22 at 12:54
-1

We can do something as simple as the following, which is the general case

from typing import List  # native python pkg, no need to install


def list_to_string(lst: List[str]) -> str:
    return " ".join(lst)

def string_to_list(str_: str) -> List[str]:
    return str_.split("")

if we want to cater to your needs that if there is an empty string, replace it with space, we shall do the following


def list_to_string(lst: List[str]) -> str:
    ''' 
    Here we loop over the characters in a list, 
    check if character "c" is space, then append it 
    otherwise replaced with an empty string

    @param list: (List) expects a list of strings
    @returns String object of characters appended together
    '''
    return " ".join([c if c not c.isspace() else "" for c in lst])

Why am I following a one-liner approach? This is due to the fact that Pythonic approaches are better IMHO as they are more readable, compact, and neat i.e. Pythonic

Yet we can also implement the solutions using normal for loops, which is the same thing yet I prefer one-liners. And we can use string concatenation but strings are immutable objects, so every time we append to the main string we have created another string, and so on for as lengthy as the given list, which is not an optimal approach due to the increased number of variables created and memory consumption (which in your case might not be that much, but better keep an eye for that)

ElSheikh
  • 321
  • 6
  • 28
  • 2
    1. you don't need to import `List` from typing unless you plan on also annotating the list elements, 2. you're overwriting the built-in `list` function by using it as the parameter name, 3. your first two snippets don't work for OP's case, 4. your only actual solution is the same as the two existing solutions, except posted 5 minutes later, 5. `str.join` accepts generator expressions, you don't need to pass a list comprehension, 6. `str.split()` already returns a `list` you don't need to cast the output to `list`... – ddejohn May 20 '22 at 00:49
  • 1. it is not needed I know but I prefer having it in my code, feel free to further explain if needed. 2. I missed that. 3. I am using them as a build-up for the answer 4. it took some time for me to articulate my answer – ElSheikh May 20 '22 at 00:50
  • 2
    You can either annotate with `list` like so: `list_to_string(lst: list) -> str` OR use `list_to_string(lst: List[str]) -> str` to also annotate the types of the list's elements. But importing `List` just to annotate an argument as a `list` type is pretty pointless. – ddejohn May 20 '22 at 00:54
  • 1
    @ddejohn all good points, except for #5. Did you know that it's actually faster (and doesn't use any more memory) to pass `join` a list than a generator? It has to iterate twice, allocating space the first time through, so even if you give it a generator expression, it builds a list internally. It's counterintuitive for sure, especially compared to things like `any` and `all`. – CrazyChucky May 20 '22 at 12:49