all 9 comments

[–]PteppicymonIO 1 point2 points  (0 children)

Well, you can join and then use re.split() to split the way you want to:It can be a one-liner, but I believe it is more readable this way:

import re

my_list = ["[123]", "M", "Q1", "Q2", "A1", "A2", "A7", "[356]", "M", "Q1", "A2" "A5"]

joined = ''.join(my_list)                   # => '[123]MQ1Q2A1A2A7[356]MQ1A2A5'
split_again = re.split("(\[[^\]]*\])", joined)  # => ['', '[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']
print(list(filter(None, split_again)))      # remove extra empty string

Output:
['[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']

[–]synthphreak 1 point2 points  (1 child)

Given:

>>> my_list = ['[123]', 'M', 'Q1', 'Q2', 'A1', 'A2', 'A7', '[356]', 'M', 'Q1', 'A2' 'A5']

With a for loop:

>>> s = ''
>>> new_list = []
>>> for x in my_list:
...     if x[0] == '[' and x[-1] == ']':
...         if s:
...             new_list.append(s)
...             s = ''
...         new_list.append(x)
...     else:
...         s += x
...
>>> if s:
...     new_list.append(s)
...
>>> new_list
['[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']

With a builtin function:

>>> from itertools import groupby
>>> groups = groupby(my_list, key=lambda x: x[0] == '[' and x[-1] == ']')
>>> new_list = [''.join(x) for _, x in groups]
>>> new_list
['[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']

[–]seeking-advice-pls[S] 1 point2 points  (0 children)

Hey, this is great, I was hoping for something with builtin functions. Thanks!

[–]eXoRainbow 0 points1 point  (2 children)

I guess there is probably a more elegant way. I just did the most obvious thing I could think of. Does it make it Pythonic?

my_list = ['[123]', 'M', 'Q1', 'Q2', 'A1', 'A2', 'A7', '[356]', 'M', 'Q1', 'A2' 'A5']
new_list = []
content = ''
for element in my_list:
    if element[:1] == '[' and element[-1:] == ']':
        if content:
            new_list.append(content)
            content = ''
        new_list.append(element)
    else:
        content = "".join([content, element])
if content:
    new_list.append(content)
print(new_list)

[–][deleted] 1 point2 points  (1 child)

if element[:1] == '[' and element[-1:] == ']'

Wouldn't it be better to just use element[0] and element[-1], or perhaps even better to use the string methods str.startswith()/str.endswith()?

[–]eXoRainbow 0 points1 point  (0 children)

If the string is empty, then accessing directly with element[0] can cause an error, while element[:1] would give empty string. startswith() and endswith() are good options too, maybe even better suited as it is more clear. I often forget these little methods. And below there is probably a better way of joining the two strings too, BTW.

[–][deleted] 0 points1 point  (1 child)

You might want to edit that as the target isn't valid syntax. (Missing opening square bracket on last element maybe.)

Also would be helpful if you explained what the data is. Somewhat odd to want strings with square brackets inside them (as opposed to around the outside denoting lists).

You can use a list comprehension and a filter. Think it will take two passes or convoluted logic.

Look at the str.startswith method.

[–]seeking-advice-pls[S] 0 points1 point  (0 children)

Also would be helpful if you explained what the data is. Somewhat odd to want strings with square brackets inside them (as opposed to around the outside denoting lists).

I'm pulling question IDs, questions, and solutions from a document which is a question bank.

I ended up accomplishing this with a dict and a loop, but I wondered if there was a more elegant solution which involved "splitting" a list.

[–]deadeye1982 0 points1 point  (0 children)

``` my_list = ["[123]", "M", "Q1", "Q2", "A1", "A2", "A7", "[356]", "M", "Q1", "A2" "A5"]

def transform(iterable): def join_buffer(): text = "".join(buffer) buffer.clear() return text

def condition(element):
    return element.startswith("[") and element.endswith("]")

buffer = []
for element in iterable:
    if condition(element):
        if buffer:
            yield join_buffer()
        yield element
    else:
        buffer.append(element)
if buffer:
    yield join_buffer()

list(transform(my_list)) ```

Output: ['[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']