2011-06-25 42 views
8

要么这是一个错误,要么我要学习一些关于Python行为的新东西。 :)Python的str.rstrip()函数中的错误,还是我自己的愚蠢?

我有一个字典填充键/值对。每个密钥都有一个唯一的前缀,ias_XX_XX_。我试图获得字典中每个唯一前缀的列表。

  1. 首先我得到一个以'_x1'结尾的所有键的列表。
  2. 接下来,我使用rstrip('_x1'从它们全部剥离'_x1')。

这对所有人都适用,除了最后一个,ias_1_1_x1。而不是被剥离到ias_1_1,它变成ias_。运行代码,看看自己:

d = { 
'ias_16_10_x2':  575, 
'ias_16_10_x1':  0, 
'ias_16_10_y1':  0, 
'ias_16_10_y2':  359, 
'ias_16_9_x2':  575, 
'ias_16_9_x1':  0, 
'ias_16_9_y1':  18, 
'ias_16_9_y2':  341, 
'ias_1_1_y1':  0, 
'ias_1_1_y2':  359, 
'ias_1_1_x2':  467, 
'ias_1_1_x1':  108, 
} 

x1_key_matches = [key for key in d if '_x1' in key] 
print x1_key_matches 

unique_ids = [] 
for x1_field in x1_key_matches: 
    unique_ids.append(x1_field.rstrip('_x1')) 

print unique_ids 

实际输出:(Python的2.6,2.7和3.2(必须更改打印打印()为3.x的工作))

['ias_16_10_x1', 'ias_16_9_x1', 'ias_1_1_x1'] 
['ias_16_10', 'ias_16_9', 'ias'] # <<<--- Why isn't this last one ias_1_1??? 

期望输出:

['ias_16_10_x1', 'ias_16_9_x1', 'ias_1_1_x1'] 
['ias_16_10', 'ias_16_9', 'ias_1_1'] 

如果我从ias_1_1更改该键的名称类似ias_1_2ias_1_3,故障不会发生。这是为什么发生?

+0

回想起来,如果'rstrip'的参数是一个集合而不是一个列表,它可能会更加正确,而且更容易混淆。但是稍后会向Python添加集合。 –

+2

您总是可以切掉最后三个字符:'如果key.endswith(“_ x1”)]'',键为uids = [key [: - 3]。请注意'endswith'与您运行的测试不一样。 – katrielalex

回答

20

的参数rstrip()是一组字符被剥离,而不是一个精确的字符串:

>>> "abcbcbaba".rstrip("ab") 
"abcbc" 

一般提示:如果你在某些功能怀疑的错误,读取其documentation

+6

啊哈! RTFM对我来说! :) –

+0

从来没有意识到这一点!从名称很容易误解为最终删除'东西'.. – kollery

5

docs,加上强调:

参数chars要被去除的字符串指定的字符集。如果省略或None,则chars参数默认为删除空格。 字符参数不是后缀;相反,其值的所有组合都被剥离。

4

.rstrip的参数不是我们想要去除的字符串,而是我们想要去除的字符。检查的例子:

>>> "12345678".rstrip("158") 
'1234567' 
>>> "12345678".rstrip("asd8qwe") 
'1234567' 
>>> "12345678".rstrip("78") 
'123456' 
>>> "1234568788".rstrip("78") 
'123456' 
2

尝试了这一点,而不是:

unique_ids.append(re.sub('_x1$', '', x1_field) 
+3

谢谢。我最终使用'unique_ids.append(x1_field.rsplit('_ x1',1)[0])'。使用正则表达式解决方案的好处是什么? –

+0

不是。过早优化可能? :)但我不知道哪一个是最快的。 –

+3

但是我必须承认,我更喜欢你的解决方案......并且基于一些非常快速的测试,它似乎至少是重新测试的两倍。注意自我:不要依赖正则表达式来处理所有事情。 –

0

rstrip返回尾随删除字符字符串的副本。

例如:

>>> ' spacious '.rstrip() 
' spacious' 
>>> "AABAA".rstrip("A") 
'AAB' 
>>> "ABBA".rstrip("AB") # both AB and BA are stripped 
'' 
>>> "ABCABBA".rstrip("AB") 
'ABC' 

######## 

>>> ' spacious '.rstrip() 
' spacious' 
>>> 'mississippi'.rstrip('ipz') 
'mississ' 

如果您正在使用的文件名打交道要格外小心,

>>> "cosmac.csv".replace(".csv") 
'cosma' 
>>> "cosmac.csv".replace(".csv", "") 
'cosmac' 

希望这有助于!