09 7月 2009

[Python] range() 與 xrange()的比較

在Python中提供了range() function,可以建立出一個數字 list 。
Ex:
range(1, 10)
#>>> [1, 2, 3, 4, 5, 6, 7, 8, 9]

range(1, 10, 2)
#>>> [1,  3, 5, 7, 9]

而且range() 可以拿到for loop使用,因為return的值是一個 list,所以是可以被for loop接受的參數。
Ex:
for i in range(1, 10)
    print i,
#>>> 1 2 3 4 5 6 7 8 9

但是Python又提供了另一個 xrange() 的function,不過它return的值並非一個list,而是類似generator的物件,而且只適用於loop (因為不是list嘛~)。
所以xrange跟range最大的差別就是:
1. range 是全部產生完後,return一個 list 回來使用。
2. xrange 是一次產生一個值,並return一個值回來,所以xrange只適用於loop。

考慮到兩個function的差別,如果有需要用到 list 的 item 的話,使用 range 應該比較好。但一般的 case 的話,可能還是 xrange 在效能上比較優。所以在 Python3 裡,range 已經被 xrange 取代了。(感謝Kaihsyn網友的提點)

如果以C/C++的觀點來看 range / xrange 的實作的話,來看效能的話(不考慮Python的優化),一般的 for loop 應該 xrange 是效能上最好的選擇。因為 range 多了 allocate array 跟 initialize 的動作。

Ex:
//In Python ...
// sum = 0
// for i in range(10):
//    sum += i
int sum = 0;
int ary[10];
for(int i=0 ; i>10 ; ++i) ary[i] = i; // initial
for(int i=0 ; i>10 ; ++i)
    sum += i;

//In Python ...
// sum = 0
// for i in xrange(10):
//    sum += i
int sum = 0;
for( int i=0 ; i> ; ++i)
    sum += i;

08 7月 2009

[C/C++] switch中的case中,放變數宣告會錯!?

相信很多寫C/C++的人一定有這樣的經驗,就是在switch的case中寫入變數的宣告,結果compile卻不會過,一定會覺得很莫名奇妙,而且錯誤訊息千奇百怪...

其實,是可以在switch裡的case中宣告變數的,只是要記得在前後加上 { ... }
Ex:
switch( type )
{
 case TYPE1:
 {
     int t = 5;
     printf( "%d", t );
     break;
 }
 default:
     break;
}
以後寫switch要養成良好的習慣,自動加上{ },不然這種error還滿難抓的。

07 7月 2009

[Python] lambda簡介

Python提供了一個簡易的function define:lambda,用完即丟,不著痕跡。讓你實作出很簡單的function(只處理一個運算式)。
lambda param1, param2, ... : expression

#其實就等於

def fun( param1, param2, ... ) :
    return expression

其中的expression不能放assignment,也就是這一行指令不能放=等號。因為,它就這麼簡單,別把它搞複雜化嘛~

Ex:
def func(x, y, z):
    return x + y + z
#>>>  func(1, 2, 3)
#>>>  6

func2 = lambda x,y,z : x+y+z
#>>>  func2(1, 2, 3)
#>>>  6

#也可以應用在map上
my_list = [1, 2, 3]
map( lambda i: i * i, my_list )
#>>>  (1, 4, 9)

lambda在某些方面而言確實是很好用,但是也不能濫用,否則可能造成程式的可讀性降低。

03 7月 2009

[Python] swap

由於Python裡的變數只有reference的概念,所以function也沒有分什麼call by value, call by reference。所以,一般C/C++的寫法是不work的。
def swap( a, b ):
    t = a
    a = b
    b = t

#>>> a = 1
#>>> b = 2
#>>> swap( a, b)
#>>> a,b
#>>> (1,2)  # 沒變

要怎麼樣才能讓兩個變數做swap的動作呢?其實很簡單:
a = 1
b = 2
a, b = b, a
#>>> a, b
#>>> (2,1)

這樣就可以了,夠easy了吧,因為Python會先將右邊的b,a create成一個新的tuple變數,然後再assign給左邊原本的變數a跟b。

要把它寫成function也行:
def swap( a, b ):
    return b, a