2014-02-11 5 views
3

я строка из букв и цифр, и я хочу их список сгруппированы по два, то есть у меня есть:Возвращает список строк, сгруппированные двумя

shv = "abcdef" 

И я хочу:

('ab'; 'cd', 'ef') 

я могу сделать:

thv = (shv[0:2], shv[2:4], shv[4:6]) 

Но почему-то это кажется немного ungeneric: есть лучший способ, то есть для строки с любым ИДСОМ е и с другим значением группировки (по группам п букв, например)

+1

В вашем примере вы показываете кортеж (игнорируя опечатку, где вы хотите запятую, а не точку с запятой). –

ответ

5

Вы можете использовать список понимание и использовать step аргумент range:

[shv[i:i+2] for i in range(0, len(shv)-1, 2)] 

Для произвольного n:

def my_awesome_grouping_function(shv, n): 
    return [shv[i:i+n] for i in range(0, len(shv)-(n-1), n)] 

Демо:

>>> shv="abcdef" 
>>> [shv[i:i+2] for i in range(0, len(shv)-1, 2)] 
['ab', 'cd', 'ef'] 
>>> [shv[i:i+3] for i in range(0, len(shv)-2, 3)] 
['abc', 'def'] 

Я обрезается верхняя граница, потому что Я решил, что вам не нужны никакие завершающие неполные пары. Вы? Если вы просто перейдете на len(shv), я верю, что вы получите оставшиеся len(shv) % n буквы в последнем элементе.

>>> shv="abcdefgh" 
>>> [shv[i:i+3] for i in range(0, len(shv), 3)] 
['abc', 'def', 'gh'] 
>>> [shv[i:i+3] for i in range(0, len(shv)-1, 3)] 
['abc', 'def', 'gh'] 
>>> [shv[i:i+3] for i in range(0, len(shv)-2, 3)] 
['abc', 'def'] 

(Как вы видите выше, это должно быть len(shv)-(n-1) для обрезки работать.)

+0

@DSM. Я думаю, что он технически работает даже для строк длины, но вы абсолютно правы: P. Если 2rs2ts исправляет это, но я дам ему свою поддержку, так как это самый лучший способ делать то, что хочет OP. –

+0

@DSM Я разместил это без тестирования, надеясь, что не ошибся. позвольте мне проверить и исправить – 2rs2ts

+0

шаг диапазона на 'n' – corn3lius

0
shv = "abcdef" 
[''.join(item) for item in zip(shv[0::2],shv[1::2])] 
+0

Это приводит к '[('a', 'b'), ('c', 'd'), ('e', 'f')]' ... –

+0

@TimPietzcker Хорошая фиксация, исправлена. –

+0

'shv [0 :: 2], shv [1 :: 2]' как-то кажется менее приятным, чем '* [iter (shv)] * 2' – njzk2

2

Как о

>>> import re 
>>> re.findall("..", shv) 
['ab', 'cd', 'ef'] 

Для произвольной длины (например 3), использовать {n} квантор:

>>> shv = "abcdefghi" 
>>> re.findall(".{3}", shv) 
['abc', 'def', 'ghi'] 

Если вы хотите использовать оставшиеся буквы, которые не полностью совпадают, используйте {1,n}:

>>> shv = "abcdefghijk" 
>>> re.findall(".{1,3}", shv) 
['abc', 'def', 'ghi', 'jk'] 
+0

Возможно, нужно добавить ''. " * n' для произвольной группировки. – Ford

+0

Я ... да. Он короткий, опрятный, чем диапазоны и срезы, и избегает думать о граничных значениях и ошибках «один за другим», но, тем не менее, я чувствую противоречие в использовании регулярных выражений. Не знаю, почему. Однако, несмотря на это. – user2357112

+0

Вам не нужен флаг 'DOTALL'? – user2357112

1

Вот путь с регулярными выражениями.

import re 

shv = "abcdef" 
print re.findall('..',shv) 
4

Я бы с textwrap для этого, дает элегантное решение:

>>> import textwrap 
>>> 
>>> shv = "abcdef" 
>>> thv = textwrap.wrap(shv, 2) 
>>> thv 
['ab', 'cd', 'ef'] 

Если у вас есть несоответствие размера это то, что вы получите:

>>> thv = textwrap.wrap(shv, 4) 
>>> thb 
['abcd', 'ef'] 

Если вы только хотите включить «полные» подстроки, вы можете использовать следующее понимание:

>>> thv = [substr for substr in textwrap.wrap(shv, 4) if len(substr) == 4] 
>>> thv 
['abcd'] 
+0

Возможно, последнее понимание могло бы лучше выражаться как 'thv = textwrap.wrap (shv, 4)', а затем 'thv = thv if len (thv [-1]) == 4 else thv [: len (thv) -1] '? – 2rs2ts

+0

@ 2rs2ts да, я полагаю, что короткая запись всегда будет последней – wnnmaw

+0

'textwrap.wrap ('как dfgh', 2) == ['as', 'df', 'gh']' – user2357112

2

хороший маленький трюк с скопированных итераторы.

tuple(''.join(i) for i in zip(*[iter(shv)]*2)) 

альтернативного вариант, если вы чувствуете сентиментальным печальный одинокий характер, оставшись в конце нечетной строки длиной.

from itertools import izip_longest 
tuple(''.join(i) for i in izip_longest(*[iter(shv)]*2, fillvalue='')) 
Смежные вопросы