2014-01-11 55 views
0

我試圖通過將它們的ascii值移動2(使用ord())來更改字符串中的字符。 這是我做到了使用for循環:列表理解和for循環的結果不一樣

s='cde' 
for i in s: 
    i=chr(ord(i)-2) 
print s 

這只是給了我原來的字符串 - 'cde'代替'abc'。然而,使用列表理解給了我正確的答案:

str='cde' 
str=''.join([chr(ord(i)-2) for i in str]) 
print str 

結果:'abc'。這兩個代碼片段都不是一回事嗎?爲什麼沒有第一個工作?

+1

不,他們不是。字符串是不可變的。 –

+2

@AshwiniChaudhary:那是真的,但即使's'是一個列表,它在這裏也不會改變.. – DSM

+0

@DSM你是對的它沒有。 –

回答

3

在您的例子

s='cde' 
for i in s: 
    i=chr(ord(i)-2) 
print s 

可變i接收複製字符串的項目的(讀: 「字符」)。更改i不會更改該字符串項目。

3

在for循環塊,

for i in s: 
    i=chr(ord(i)-2) 

i點到每個和迭代對象s的每個元素。但是,當您將某物分配給i時,它只是指向分配的項目,而保留原始項目不變。你可以用這個程序來確認。

s='cde' 
for i in s: 
    print id(i) 
    i=chr(ord(i)-2) 
    print id(i) 
print map(id, s) 

id函數返回python對象的唯一id。在每次迭代中,它都會打印兩個ID。第一個對應於字符串中元素的id,但第二個對應於分配的元素。

另一方面,列表理解會創建一個新列表並加入。這就是爲什麼變革反映在那裏。

0

您的第一個不會修改字符串。循環變量(您的案例中的i)沒有引用它生成的字符串,因此更改它並不反映在字符串中(這是不可變的)。例如:

s = "abc" 
for index, char in enumerate(s): 
    char = 'z'   #we assign tp the loop variable. the actual string is unchanged. 
    print(char)   #prints 'z' 
    print(s[index])  #prints the original char from the string, a -> b -> c 

你的第二個例子直接分配給字符串,所以它被改變了。

爲了讓你的第一個技術工作,試試這個:

s='cde' 
temp = '' 
for i in s: 
    temp = str.join([temp, chr(ord(i)-2)]) 
s = temp 
2

字符串是不可改變的,但是這用於分配失敗的原因在for循環中,見下面的代碼:

In [272]: l=list('asdf') 

In [273]: l 
Out[273]: ['a', 's', 'd', 'f'] 

In [274]: for i in l: 
    ...:  i=chr(ord(i)+1) 
    ...:  

In [275]: l 
Out[275]: ['a', 's', 'd', 'f'] 

列表對象是可變的,但仍然分配變化什麼l,因爲i=chr(ord(i)+1)只是讓i指nother string

2.在這種情況下,我們如何更改/替換列表中的值?

列表是可變的,你可以使用l[i]指一個項目在l,使用enumerate讓你拿到指標迭代時:

In [299]: for i, v in enumerate(l): 
    ...:  l[i]+='z' 
    ...:  

In [300]: l 
Out[300]: ['az', 'sz', 'dz', 'fz'] 

即g雖然l是可變的,l[0]是仍然是不可變的:

In [301]: l=list('asdf') 

In [302]: id(l[0]) 
Out[302]: 33639888 

In [303]: for i, v in enumerate(l): 
    ...:  l[i]+='z' 

In [304]: l 
Out[304]: ['az', 'sz', 'dz', 'fz'] 

In [305]: id(l[0]) #what l[0] refers to has been changed 
Out[305]: 110316288 
+0

如何在這種情況下更改/替換列表中的值? –

+0

@VineetKaushik您通常不應該更改您正在迭代的列表 - 只需創建另一個列表或使用列表理解(如果需要的話)。 –

+0

@VineetKaushik回答更新:) – zhangxaochen