Python .join()可迭代字符串

时间:2013-12-11 07:54:30

标签: python string iterable

我正在尝试找到一种简单的方法,将每个3位数字点.添加为字符串('43434' -> '43.434),我发现有一个有趣的连接用于此任务:

num = '1234567'
new_num = '.'.join(num[i:i+3] for i in range(0, len(num), 3))
# new_num = 123.456.7'

它接近我想要的。这就是我想要的:

(its need to be `'1.234.567'`)

为什么会这样? 当我在连接上使用切片时,它会为每个项添加添加:

num = '2333'
>>> '.'.join(num[0:2])
<<< '2.3'
>>> '.'.join(num[0:3])
<<< '2.3.3'

我在某个地方读到了它被称为可迭代概念的字符串。有人可以帮我理解吗?

6 个答案:

答案 0 :(得分:4)

您的第一个代码示例一次获取3位数字并加入它们。打破它

>>>num = '1234567'
>>>x=[num[i:i+3] for i in range(0, len(num), 3)]
>>>x
['123', '456', '7']
>>>'.'.join(x)
'123.456.7'

num[i:i+3]部分称为切片并解释here

在第二部分中,您使用join function再次连接部件。

>>>num = '2333'
>>>num[0:2]
23 
>>>'.'.join('23')
2.3

你想要的是1.234.567,即你想从字符串的 end 开始计算三位数。一种方法是反转字符串,做你正在做的事情并反转结果。

>>> num = '1234567'
>>> num[::-1]
'7654321'
>>> '.'.join(num[::-1][i:i+3] for i in range(0, len(num), 3))[::-1]
'1.234.567'

答案 1 :(得分:3)

可能的方式,

>>> num = '1234567'
>>> '.'.join([num[i-3 if i-3 > 0 else 0:i] for i in range(len(num),-1,-3)][::-1])
'1.234.567'

基准,

$ python -mtimeit -s'num="1234567"' '".".join(num[::-1][i:i+3] for i in range(0, len(num), 3))[::-1]'
100000 loops, best of 3: 4.15 usec per loop

$ python -mtimeit -s'num="1234567"' '".".join([num[i-3 if i-3 > 0 else 0:i] for i in range(len(num), -1, -3)][::-1])'
1000000 loops, best of 3: 1.87 usec per loop

对我来说,两者都不是更清楚,但如果你更喜欢第一个(流行的解决方案)它只会稍微慢一些。

答案 2 :(得分:2)

如果您尝试:

>>> a = (num[i:i+3] for i in range(0, len(num), 3))
>>> a
<generator object <genexpr> at 0x028C2B48>

所以第一个主要是使用:

new_num = '.'.join(a) # iterating with generator

或者,您可以使用list

new_num = '.'.join([num[i:i+3] for i in range(0, len(num), 3)]) 
# iterating with list ['123', '456', '7']

这也解释了您的代码,因为您可以将string视为list

'.'.join(num[0:3]) # num[0:3] -> '233' string -> ['2', '3', '3']

答案 3 :(得分:1)

粗略地说,迭代是什么,这段代码将起作用:

for x in some_iterable_here:
    print(x)

这个想法是一个iterable是一系列值。列表是可迭代的。如果some_iterable_here[1, 23, -7, 'hello']列表,则上面的代码会打印出数字123-7,最后是字符串'hello'

字符串是一种可迭代的 - 它是一系列字符。因此,如果您为'hello'添加字符串some_iterable_here,则会分别打印出每个字母:'h''e''l',{{1} },然后最后'l'

'o'所做的是将包含字符串的iterable中的每个元素(例如,像join这样的字符串列表,或只是字符串['one', 'two', 'three'],它是一个包含字符串的迭代字符串'four''f''o''u')并返回一个新字符串,其中包含所有字符串放在一起的字符串。

所以当你得到切片'r'时,就是字符串num[0:3]。当你对它'233'进行'.'.join时,Python会将每个字符与句点组合在一起,这就是'2.3.3'的结果。

答案 4 :(得分:1)

尝试此解决方案

(".".join([num[::-1][i:i+3] for i in range(0, len(num), 3)]))[::-1]

答案 5 :(得分:1)

如果我理解你:

In [15]: num = '1234567'
#Reverse string with [::-1]
In [16]: new_num = '.'.join(num[::-1][i:i+3] for i in range(0, len(num), 3))
#Repeat reverse for correct result
In [17]: new_num = new_num[::-1]
In [18]: print new_num
1.234.567