2013-08-01 50 views
11

我需要在Python中掃描一個列表。我能夠從文件加載,並做簡單的操作,但我試圖做到以下幾點:掃描一個列表

L = [1,2,3,4,5,6,7,8] 

從第一個元素開始,我要產生下面的輸出:

1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
4 
    5,6,7,8 
    6,7,8 
    7,8 
    8 

等等。

我是想這樣的事情:

fo = open(sys.argv[1], 'r') 
L = fo.readlines() 
for i in range(len(L)): 
    print str(L[i]) 
    for j in range(len(L)-1-i): 
     print '...' + str(L[i+j+1]) 

你能幫助我嗎?

+0

我很困惑...您打印的列表從1,3,4,5,6,7和8開始,然後從2,4,5,6,7,8開始,然後是3,5, 7 ...我看不到這個模式,你能明確嗎? – Jblasco

+0

我只想補充說,最好是使用open(sys.argv [1],「r」)做fo: #用fo做東西,因爲這樣文件就會自動關閉,即使處理它時會發生錯誤。只是好的做法。 – rlms

回答

13

這是怎麼回事?尼斯和簡單閱讀:

>>> for i, j in enumerate(L): 
...  print L[i] 
...  temp = map(str, L[j:]) 
...  while temp: 
...    print ' ', ','.join(temp) 
...    temp = temp[1:] 
... 
1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
... 

while temp手段,而列表temp不是空的。我們要在這裏呼籲map(str, L[j:])因爲列表已滿整數(因此str.join方法是行不通的)


又一個音符,它在處理文件時更Python的使用with聲明:

with open(sys.argv[1], 'r') as fo: 
    L = fo.readlines() 
+0

非常好,但它是用戶想要什麼?看到我上面的評論。 – Jblasco

+2

@Jblasco它似乎與他在他的問題 – TerryA

+0

中提供的輸出完全相同現在,你是對的。它之間進行了編輯。 – Jblasco

4

雖然Haidro答案產生了所需的輸出,但我應該說這是相當低效的算法來完成所提供的任務。

快速分析:

for i, j in enumerate(L):   # loop number 1, for i from 1 to N 
    print L[i] 
    temp = map(str, L[j:])   
    while temp:     # nested loop number 2, for j from i to N 
     print ' ', ','.join(temp) # nested loop number 3, for k from j to N 
     temp = temp[1:] 

它是這樣一個簡單的任務太多的工作。我認爲它可以做得更簡單和更快,只需將字符串加入一次,然後打印子字符串(如DCM中提到的,爲了能夠打印任意數字,我們應該預先計算字符串中元素的位置):

s = ",".join(map(str, l))     # creating string 
p = [len(str(x)) + 1 for x in l]   # calculating length of each element 
p = [sum(p[:i]) for i in range(len(p))] # calculating positions with rolling total 
for i in range(len(l)):     # loop number 1 
    print l[i] 
    for j in range(i + 1, len(l)):   # nested loop number 2 
     print ' ', s[p[j]:] 

下面是執行時間的快速簡介(我用海德羅碼創建了函數worker1,用我的函數創建了worker2)。你可以看到如何生長的執行時間,當你增加輸入長度N:

>>> from timeit import timeit 

>>> timeit("worker1(l)", "from testSO import worker1, l", number=10) 
0.0016222212978796024 
>>> timeit("worker1(l*10)", "from testSO import worker1, l", number=10) 
0.33153371422580324 
>>> timeit("worker1(l*100)", "from testSO import worker1, l", number=10) 
163.25908817145972 

它變得像O(N^3)

>>> timeit("worker2(l)", "from testSO import worker2, l", number=10) 
0.0006974355000011201 
>>> timeit("worker2(l*10)", "from testSO import worker2, l", number=10) 
0.03448374103493279 
>>> timeit("worker2(l*100)", "from testSO import worker2, l", number=10) 
4.446190059150922 

這一次變得像O(N^2)

這並不是說我認爲原問題看起來像性能關鍵任務,但我認爲如果人們明白爲什麼提供的算法可能比他們預期的要慢,那將會很好。

+1

這樣雖然性能更好,但是寫得比較差。如果數字的長度不總是1,它不會給出預期的結果。 – DSM

+0

@DSM,很好的一點,錯過了,我會檢查它 –

+0

@DSM改變了預先計算的元素位置的答案 –