每隔第n个字符拆分字符串?

时间:2012-02-28 01:48:25

标签: python

是否可以每隔第n个字符拆分一个python字符串?

例如,假设我有一个包含以下内容的字符串:

'1234567890'

如何让它看起来像这样:

['12','34','56','78','90']

26 个答案:

答案 0 :(得分:464)

>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']

答案 1 :(得分:174)

为了完成,您可以使用正则表达式执行此操作:

>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']

正如评论中指出的那样,你可以这样做:

>>> import re
>>> re.findall('..?', '123456789')
['12', '34', '56', '78', '9']

您还可以执行以下操作,以简化较长块的正则表达式:

>>> import re
>>> re.findall('.{1,2}', '123456789')
['12', '34', '56', '78', '9']

如果字符串很长,你可以使用re.finditer来按块生成块。

答案 2 :(得分:74)

将元素分组为n长度组的另一种常用方法:

>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']

此方法直接来自zip()的文档。

答案 3 :(得分:63)

python中已经有一个内置函数。

>>> from textwrap import wrap
>>> s = '1234567890'
>>> wrap(s, 2)
['12', '34', '56', '78', '90']

这就是换行的文档字符串:

>>> help(wrap)
'''
Help on function wrap in module textwrap:

wrap(text, width=70, **kwargs)
    Wrap a single paragraph of text, returning a list of wrapped lines.

    Reformat the single paragraph in 'text' so it fits in lines of no
    more than 'width' columns, and return a list of wrapped lines.  By
    default, tabs in 'text' are expanded with string.expandtabs(), and
    all other whitespace characters (including newline) are converted to
    space.  See TextWrapper class for available keyword args to customize
    wrapping behaviour.
'''

答案 4 :(得分:52)

我认为这比itertools版本更短,更易读:

def split_by_n(seq, n):
    '''A generator to divide a sequence into chunks of n units.'''
    while seq:
        yield seq[:n]
        seq = seq[n:]

print(list(split_by_n('1234567890', 2)))

答案 5 :(得分:21)

我喜欢这个解决方案:

s = '1234567890'
o = []
while s:
    o.append(s[:2])
    s = s[2:]

答案 6 :(得分:18)

使用PyPI中的more-itertools

>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']

答案 7 :(得分:11)

您可以使用grouper()中的itertools食谱:

Python 2.x:

from itertools import izip_longest    

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

Python 3.x:

from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

这些函数具有内存效率,适用于任何迭代。

答案 8 :(得分:5)

尝试一下:

s='1234567890'
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])

输出:

['12', '34', '56', '78', '90']

答案 9 :(得分:4)

请尝试以下代码:

from itertools import islice

def split_every(n, iterable):
    i = iter(iterable)
    piece = list(islice(i, n))
    while piece:
        yield piece
        piece = list(islice(i, n))

s = '1234567890'
print list(split_every(2, list(s)))

答案 10 :(得分:4)

>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x)]
['12', '34', '56', '78', '90']
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
['123', '456', '789']

答案 11 :(得分:3)

这可以通过简单的for循环来实现。

a = '1234567890a'
result = []

for i in range(0, len(a), 2):
    result.append(a[i : i + 2])
print(result)

输出看起来像 ['12','34','56','78','90','a']

答案 12 :(得分:2)

一如往常,对于喜欢一个衬垫的人

n = 2  
line = "this is a line split into n characters"  
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]

答案 13 :(得分:1)

我已经使用了这个代码,只要我需要这样做:

def split_string(n, st):
    lst = [""]
    for i in str(st):
        l = len(lst) - 1
        if len(lst[l]) < n: 
            lst[l] += i
        else:
            lst += [i]
    return lst

print(split_string(3, "test_string."))

其中:

  • n是每个列表项的长度
  • st是要拆分的字符串
  • lstst
  • 的列表版本
  • ist
  • 中使用的当前字符
  • l是最后一个列表项的长度

答案 14 :(得分:0)

我陷入了同一个场景。

这对我有用

x="1234567890"
n=2
list=[]
for i in range(0,len(x),n):
    list.append(x[i:i+n])
print(list)

输出

['12', '34', '56', '78', '90']

答案 15 :(得分:0)

这可能会更清楚

##Define your string
mystring = '1234567890'

##Define your starting index
start = 0
##Define the end of your index for the first slice
end = 2

##Create an empty list
mylist =[]

##While the slice of characters without white space has something in it keep going
while len(mystring[start:end])>0:
    ##Add to the list
    mylist.append(mystring[start:end])
    ##Move the index up for the begining and ending of the slice
    start+=2
    end+=2

答案 16 :(得分:0)

这个问题使我想起了Perl 6 .comb(n)方法。它将字符串分成n个大小的块。 (不止如此,但我将省略细节。)

很容易在Python3中实现类似的功能作为lambda表达式:

comb = lambda s,n: [s[i:i+n] for i in range(0,len(s),n)]

然后您可以这样称呼它:

comb('1234567', 2)   # returns ['12', '34', '56', '7']

comb()函数还将对列表起作用(产生列表列表):

comb(['cat', 'dog', 'bird'], 2)  # returns [['cat', 'dog'], ['bird']]

答案 17 :(得分:0)

一种可能是使用正则表达式:

import re
re.findall("\w{3}", your_string)

答案 18 :(得分:0)

使用 groupby 的解决方案:

from itertools import groupby, chain, repeat, cycle

text = "wwworldggggreattecchemggpwwwzaz"
n = 3
c = cycle(chain(repeat(0, n), repeat(1, n)))
res = ["".join(g) for _, g in groupby(text, lambda x: next(c))]
print(res)

输出:

['www', 'orl', 'dgg', 'ggr', 'eat', 'tec', 'che', 'mgg', 'pww', 'wza', 'z']

答案 19 :(得分:0)

短字符串的简单递归解决方案:

def split(s, n):
    if len(s) < n:
        return []
    else:
        return [s[:n]] + split(s[n:], n)

print(split('1234567890', 2))

或采用以下形式:

def split(s, n):
    if len(s) < n:
        return []
    elif len(s) == n:
        return [s]
    else:
        return split(s[:n], n) + split(s[n:], n)

,它更清晰地说明了递归方法中的典型分而治之模式(尽管实际上没有必要这样做)

答案 20 :(得分:0)

我知道这个问题很旧,但这是我知道的最短的解决方法:

def split_every_n(S, n):
  return [S[i*n:(i+1)*n] for i in range(len(S) / n)]

但是,这假定字符串的长度是n的倍数。否则,您必须将其垫上。

答案 21 :(得分:0)

之前

more_itertools.slicedmentioned。以下是more_itertools库中的另外四个选项:

s = "1234567890"

["".join(c) for c in mit.grouper(2, s)]

["".join(c) for c in mit.chunked(s, 2)]

["".join(c) for c in mit.windowed(s, 2, step=2)]

["".join(c) for c in  mit.split_after(s, lambda x: int(x) % 2 == 0)]

后面的每个选项都会产生以下输出:

['12', '34', '56', '78', '90']

讨论选项的文档:grouperchunkedwindowedsplit_after

答案 22 :(得分:0)

 INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)  
 INFO: HHH000115: Hibernate connection pool size: 20  
 INFO: HHH000006: Autocommit mode: true  
 INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]  
 INFO: HHH000046: Connection properties: {user=root, autocommit=true, release_mode=auto}  
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect  
 INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory  
 INFO: HHH000397: Using ASTQueryTranslatorFactory  
 INFO: HHH000228: Running hbm2ddl schema update  
 INFO: HHH000102: Fetching database metadata  
 INFO: HHH000396: Updating schema  
 INFO: HHH000261: Table found: test.account  
 INFO: HHH000037: Columns: [balance, name, id, accnumber, sortcode]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer  
 INFO: HHH000037: Columns: [password, city, street, county, name, id, login, email, token]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer_account  
 INFO: HHH000037: Columns: [account_id, customer_id]  
 INFO: HHH000108: Foreign keys: [fk70eacecc22b4f18d, fk70eacecc3a281067]  
 INFO: HHH000126: Indexes: [fk70eacecc22b4f18d, fk70eacecc3a281067, account_id]  
 INFO: HHH000261: Table found: test.hibernate_sequences  
 INFO: HHH000037: Columns: [sequence_next_hi_value, sequence_name]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: []  
 INFO: HHH000232: Schema update complete  
 WARN: HHH000436: Entity manager factory name (Bank) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'  
 INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)  
 INFO: HHH000115: Hibernate connection pool size: 20  
 INFO: HHH000006: Autocommit mode: true  
 INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]  
 INFO: HHH000046: Connection properties: {user=root, autocommit=true, release_mode=auto}  
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect  
 INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory  
 INFO: HHH000397: Using ASTQueryTranslatorFactory  
 INFO: HHH000228: Running hbm2ddl schema update  
 INFO: HHH000102: Fetching database metadata  
 INFO: HHH000396: Updating schema  
 INFO: HHH000261: Table found: test.account  
 INFO: HHH000037: Columns: [balance, name, id, accnumber, sortcode]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer  
 INFO: HHH000037: Columns: [password, city, street, county, name, id, login, email, token]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer_account  
 INFO: HHH000037: Columns: [account_id, customer_id]  
 INFO: HHH000108: Foreign keys: [fk70eacecc22b4f18d, fk70eacecc3a281067]  
 INFO: HHH000126: Indexes: [fk70eacecc22b4f18d, fk70eacecc3a281067, account_id]  
 INFO: HHH000261: Table found: test.hibernate_sequences  
 INFO: HHH000037: Columns: [sequence_next_hi_value, sequence_name]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: []  
 INFO: HHH000232: Schema update complete  
 WARN: HHH000436: Entity manager factory name (Bank) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'  
 com.mycompany.bank.model.Customer@455917ff  
 Returning: com.mycompany.bank.model.Customer@302ab24b  
 INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)  
 INFO: HHH000115: Hibernate connection pool size: 20  
 INFO: HHH000006: Autocommit mode: true  
 INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]  
 INFO: HHH000046: Connection properties: {user=root, autocommit=true, release_mode=auto}  
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect  
 INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory  
 INFO: HHH000397: Using ASTQueryTranslatorFactory  
 INFO: HHH000228: Running hbm2ddl schema update  
 INFO: HHH000102: Fetching database metadata  
 INFO: HHH000396: Updating schema  
 INFO: HHH000261: Table found: test.account  
 INFO: HHH000037: Columns: [balance, name, id, accnumber, sortcode]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer  
 INFO: HHH000037: Columns: [password, city, street, county, name, id, login, email, token]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer_account  
 INFO: HHH000037: Columns: [account_id, customer_id]  
 INFO: HHH000108: Foreign keys: [fk70eacecc22b4f18d, fk70eacecc3a281067]  
 INFO: HHH000126: Indexes: [fk70eacecc22b4f18d, fk70eacecc3a281067, account_id]  
 INFO: HHH000261: Table found: test.hibernate_sequences  
 INFO: HHH000037: Columns: [sequence_next_hi_value, sequence_name]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: []  
 INFO: HHH000232: Schema update complete  
 WARN: HHH000436: Entity manager factory name (Bank) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'  
 INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)  
 INFO: HHH000115: Hibernate connection pool size: 20  
 INFO: HHH000006: Autocommit mode: true  
 INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test]  
 INFO: HHH000046: Connection properties: {user=root, autocommit=true, release_mode=auto}  
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect  
 INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory  
 INFO: HHH000397: Using ASTQueryTranslatorFactory  
 INFO: HHH000228: Running hbm2ddl schema update  
 INFO: HHH000102: Fetching database metadata  
 INFO: HHH000396: Updating schema  
 INFO: HHH000261: Table found: test.account  
 INFO: HHH000037: Columns: [balance, name, id, accnumber, sortcode]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer  
 INFO: HHH000037: Columns: [password, city, street, county, name, id, login, email, token]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: [primary]  
 INFO: HHH000261: Table found: test.customer_account  
 INFO: HHH000037: Columns: [account_id, customer_id]  
 INFO: HHH000108: Foreign keys: [fk70eacecc22b4f18d, fk70eacecc3a281067]  
 INFO: HHH000126: Indexes: [fk70eacecc22b4f18d, fk70eacecc3a281067, account_id]  
 INFO: HHH000261: Table found: test.hibernate_sequences  
 INFO: HHH000037: Columns: [sequence_next_hi_value, sequence_name]  
 INFO: HHH000108: Foreign keys: []  
 INFO: HHH000126: Indexes: []  
 INFO: HHH000232: Schema update complete  
 WARN: HHH000436: Entity manager factory name (Bank) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'  

答案 23 :(得分:0)

幽灵般的 - 试图发明另一个答案:

def split(s, chunk_size):
    a = zip(*[s[i::chunk_size] for i in range(chunk_size)])
    return [''.join(t) for t in a]

print(split('1234567890', 1))
print(split('1234567890', 2))
print(split('1234567890', 3))

停止

['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
['12', '34', '56', '78', '90']
['123', '456', '789']

答案 24 :(得分:-1)

这是针对更一般情况的另一种解决方案,其中块的长度不相等。如果长度为0,则返回所有剩余部分。

data是要拆分的序列; fieldsize是一个包含字段长度列表的元组。

def fieldsplit(data=None, fieldsize=()):
    tmpl=[];
    for pp in fieldsize:
        if(pp>0):
            tmpl.append(line[:pp]);
            line=line[pp:];
        else:
            tmpl.append(line);
            break;
    return tuple(tmpl);

答案 25 :(得分:-2)

我正在使用它:

list(''.join(s) for s in zip(my_str[::2], my_str[1::2]))

或者您可以使用任何其他n号码代替2