Гибкое разбиение входной строки в функции Python

1

В Python, что было бы самым элегантным способом преобразования этой структуры:

['group1, group2, group3']

в эту структуру:

['group1', 'group2', 'group3']

и, возможно, назад.

Требуется функция, которая может принимать либо список строк разделенных запятыми значений (первый случай), либо список строк с одинаковыми значениями (второй случай) и обрабатывать их как один и тот же: список строк.

В псевдокоде:

x = ['group1, group2, group3']
y = ['group1', 'group2', 'group3']

f(x) <==> f(y)    <- equivalent behavior

Кроме того, если вы используете split() в соответствии с предложениями:

Есть ли способ сделать пространство разделителя нечувствительным или условным или регулярным выражением: я хотел бы перейти к ['group1', 'group2', 'group3'] либо в ['group1, group2, group3'] либо ['group1,group2,group3'] или даже это ['group1, group2,group3'] (или их комбинация) в качестве входа?

Еще немного уточнений:

>>> single_string = False
>>> a = ['group1', 'group2', 'group3','group4']
>>> [t.strip() for t in [a][0].split(',')] if single_string else a
['group1', 'group2', 'group3', 'group4']
>>> single_string = True
>>> b = ['group1,group2, group3,  group4']
>>> [t.strip() for t in [b][0].split(',')] if single_string else b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'split'
>>>

В принципе, я ищу наиболее элегантное условное выражение Python, которое приведет к тому же выводу как в случае a и b выше: ['group1', 'group2', 'group3', 'group4'].

Теги:
function
split

7 ответов

1
Лучший ответ

Вы почти были в своем редактировании:

def f(lst):
    return [t.strip() for t in lst[0].split(',')] if len(lst) == 1 else lst

>>> a = ['group1', 'group2', 'group3','group4']
>>> b = ['group1,group2, group3,  group4']

>>> f(a)
['group1', 'group2', 'group3', 'group4']
>>> f(b)
['group1', 'group2', 'group3', 'group4']
3

вы можете использовать split и join чтобы перейти от одного представления к другому:

print('group1, group2, group3'.split(', '))
# ['group1', 'group2', 'group3']
print(', '.join(['group1', 'group2', 'group3']))
# group1, group2, group3

в функции вы можете это сделать:

def f(items, index, separator=', '):
    if isinstance(items, str):
        items = items.split(separator)
    return items[index]


print(f('group1, group2, group3', 1))        # group2
print(f(['group1', 'group2', 'group3'], 1))  # group2
  • 0
    может ли разделитель быть условным? ', ' или же ','. Я думаю, регулярное выражение более уместно?
  • 0
    конечно, если вам нужно разделить несколько вещей, re.split должен работать.
1

Как насчет использования split():

Код:

['group1, group2, group3'][0].split(', ')

Тестовый код:

x = ['group1, group2, group3']    
print(x[0].split(', '))

Результаты:

['group1', 'group2', 'group3']

Возвращать:

Для возврата используйте str.join()

y = x[0].split(', ')
print(y)

xx = [', '.join(y)]
print(xx)

Результаты:

['group1', 'group2', 'group3']
['group1, group2, group3']
  • 0
    Благодарю. Есть ли способ сделать нечувствительным к разделителю пространство: я хотел бы получить результат ['group1', 'group2', 'group3'] в ['group1, group2, group3'] или ['group1,group2,group3'] или даже этот ['group1, group2,group3'] (или их комбинация) в качестве входа?
  • 1
    @SimeonLeyzerzon Вы можете разделить запятую и разделить токены: y = [t.strip() for t in x[0].split(',') .
Показать ещё 1 комментарий
1

Вы можете определить функцию, используя str.split on , а затем itertools.chain результат, используя itertools.chain

>>> from itertools import chain
>>> f = lambda x: list(chain(*[a.split(', ') for a in x]))

>>> f(['group1', 'group2', 'group3'])
>>> ['group1', 'group2', 'group3']

>>> f(['group1, group2, group3'])
>>> ['group1', 'group2', 'group3']

В случае разделителя переменных и дополнительного пространства регулярное выражение будет лучшим выбором

>>> import re
>>> f = lambda x, sep: list(chain(*[re.split('{}\s*'.format(sep), a) for a in x]))
>>> f(['group1, group2,group3'],',')
>>> ['group1', 'group2', 'group3']
0

Я думаю, что это наиболее ясно, просто используя split и strip.

# various scenarios to test
TESTS = [
    ['group1, group2, group3'],
    ['group1', 'group2', 'group3'],
    ['group1,group2,  group3'],
    ['group1', 'group2, group3'],
    ['group1 ,group2', 'group3'],
]


def normalize(args, delimiter=','):
    results = []
    for arg in args:
        results.extend(x.strip() for x in arg.split(delimiter))
    return results


for args in TESTS:
    assert normalize(args) == ['group1', 'group2', 'group3']


# test alternative delimiter
assert normalize(['group1 | group2 | group3'], delimiter='|') == ['group1', 'group2', 'group3']
0

Используя str.replace() чтобы устранить все пробелы, вы можете использовать формулу, которая будет работать во всех представленных случаях.

lst = ['group1, group2, group3']

res = lst[0].replace(' ', '').split(',')
# ['group1', 'group2', 'group3']
0

split() и join() можно попробовать.

case1 = ['group1, group2, group3']
output = [ele.split(",") for ele in case1]

Выход для случая-1

[['group1', ' group2', ' group3']]

Case-2

case2 = [['group1', ' group2', ' group3']]
output = [", ".join(ele) for ele in case2]

Выход для случая-2

['group1, group2, group3']

Ещё вопросы

Сообщество Overcoder
Наверх
Меню