1

I have a list that can contain strings and integers, but I want to join all adjacent strings, only if there is no integer between those strings. For example :

list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
taken = []
for let in list_a:
    if let == 0:
        pass
    else:
        taken.append(let)

word = "".join(taken)
print(word)

>> cakeyou

I want to get either "cake" or "you" or both as two words. "Cakeyou" should not be an output because to get "cakeyou" the loop would move pass two zeros when it should stop the moment it meets any zero after reading some strings. Another important detail is that the words cake or you could be anywhere in the list, here I chose the index for simplicity (so slicing would not be a viable option)

Supernyv
  • 33
  • 9
  • _the loop would move pass two zeros_ which is exactly what You are doing with `if let == 0: pass` – Matiiss Apr 22 '21 at 10:59
  • I would use [**`itertools.groupby`**](https://docs.python.org/3/library/itertools.html#itertools.groupby). See [How do I use itertools.groupby()?](https://stackoverflow.com/questions/773/how-do-i-use-itertools-groupby) – Peter Wood Apr 22 '21 at 12:03

6 Answers6

1
list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
taken = []; toadd = ''; open = False
for c, l in enumerate(list_a):
    if type(l) != int:
        open = True
        toadd += l
    else:
        if open:
            taken.append(toadd)
        toadd = ''
        open = False
    if c == len(list_a)-1:
        if open:
            taken.append(toadd)
        toadd = ''
print(taken)
#>>>['cake', 'you']
Sid
  • 2,174
  • 1
  • 13
  • 29
1
list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
taken = []
temp = ""
for let in list_a:
    if isinstance(let, int):
        if temp:
            taken.append(temp)
            temp = ""
    else:
        temp += let

if temp:
    taken.append(temp)

print(taken)
#>>>['cake', 'you']
Marcus.Aurelianus
  • 1,520
  • 10
  • 22
1

Is this suitable for you?

list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
words = []

word = ""
for letter in list_a:
    if letter == 0 and word == "":
        pass
    elif letter == 0:
        words.append(word)
        word = ""
    else:
        word += letter

print(words)
#>>>['cake', 'you']
pudup
  • 121
  • 5
  • If you want to check for integers instead of just "0", you can replace if letter == 0 with if isinstance(letter, int) Sorry for awful formatting in this comment – pudup Apr 22 '21 at 11:23
1

You can use itertools.groupby which splits sequences based upon some key. If we say the key is that the value is a str, then we get a sequence of groups of str values. We also get a value saying whether the key evaluated True or False. We can then filter out the groups of str values and the groups of int values:

>>> from itertools import groupby

>>> values = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]

>>> for keep, group in groupby(values, key=lambda value: isinstance(value, str)):
...     if keep:
...         print(''.join(group))
cake
you
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
0

I'd suggest, you put a space when the value is an int, then join, and use strip() to emove leading and padding spaces

list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
taken = []
for let in list_a:
    if isinstance(let, int):
        taken.append(" ")
    else:
        taken.append(let)

word = "".join(taken).strip()
print(word)  # 'cake  you'
azro
  • 53,056
  • 7
  • 34
  • 70
  • I suggest replacing `word = ''.join(taken).strip()` with `word = ' '.join(word for word in "".join(taken).split() if word != '')` which is a bit longer but gets rid of unwanted spaces, for example in the case there are a lot of integers between strings, so that printing out it doesn't produce a massive space – Matiiss Apr 22 '21 at 11:04
  • @Supernyv you can think about accepting the answer so (green tick onleft) ;) – azro Apr 22 '21 at 19:02
-2

My solution: make everything a string, strip leading and trailing zeros and split by double-zero. Than just grab the first entry. (Error handling for invalid input not included)

list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
all_stringified = [str(a) for a in list_a]
word = ''.join(all_stringified).strip('0').split('00')[0]
print(word)

>> cake

For history my first answer:

My suggestion is to use a filter within a list comprehension:

list_a = [0, 0, "c", "a", "k", "e", 0, 0, "y", "o", "u", 0]
taken = [e for e in list_a if isinstance(e, str)]
word = "".join(taken)
print(word)

>> cakeyou
René Jahn
  • 1,155
  • 1
  • 10
  • 27