Connectors with a Python string in a list

Is there an elegant way (most likely using list comprehension) to combine all adjacent string elements in a list?

I have a list where there is no functional difference between several lines in a line, and all these lines are combined into one line, but for both reading and equivalence testing, I would like to combine them together. There may be other non-line items in the list that can break lines. They should remain between concatenated string groups.

For example, I could

rule = ["a", "b", C(), "d", "ef", "g"]

and instead I want

rule = ["ab", C(), "defg"]
+4
source share
5 answers

itertools.groupby - , . , str, , . "", :

rule = ["a", "b", C(), "d", "ef", "g"]
rule = [x for cls, grp in itertools.groupby(rule, type)
          for x in ((''.join(grp),) if cls is str else grp)]

, C __repr__, , :

['ab', <__main__.C at 0x1d572c98588>, 'defg']

"" listcomp . str, tuple "" ( , ); str, .

+3

, itertools.groupby chain.

from itertools import groupby, chain
isstr = lambda x: isinstance(x, basestring)
# on Python 3: lambda x: isinstance(x, str)

rule = ["a", "b", C(), "d", "ef", "g"]
list(chain.from_iterable(
    # join string groups into single-element sequence,
    # otherwise just chain the group itself
    (''.join(group), ) if group_isstr else group
    for group_isstr, group in groupby(rule, isstr)
))
['ab', <__main__.C object at 0x108dfdad0>, 'defg']
+3

itertools.groupby:

import itertools
class C:
   pass
rule = ["a", "b", C(), "d", "ef", "g"]
s = [(a, list(b)) for a, b in itertools.groupby(rule, type)]
new_s = [''.join(b) if all(isinstance(c, str) for c in b) else b[0] for a, b in s]

:

['ab', <__main__.C instance at 0x101419998>, 'defg']
0

:

def concat_str(lst):
    newlst = []
    newstr = ""
    length = len(lst)
    for index, elem in enumerate(lst):
        if(type(elem) is str):
            newstr = newstr + elem
            if(index == length -1):
                newlst.append(newstr)
        else:
            if(newstr):
                newlst.append(newstr)
            newlst.append(elem)
            newstr = ""
    return newlst
0
import re
rule= ["a", "b", 'C()', "d", "ef", "g"]
b=""
c=""

for i in range(len(rule)):
    if re.match("^[a-zA-Z0-9_]*$", rule[i]):
        b+=str(rule[i])
        ','.join(b)  
    else:
        c+=str(rule[i])
        a=b
        b=""

e=a,c,b
print(e)

<<<('ab', 'C ()', 'defg')

Using regular expressions, you can analyze the place in the list where this regular expression sits. Then, using the for loop to join the items in the list before the regular expression, this is the regular expression, which then resets the "b" and concatenates the elements in the list after the regular expression.

-1
source

Source: https://habr.com/ru/post/1688910/


All Articles