2017-10-12 71 views
0

全部,Python:使用長度作爲索引插入到列表中

我最近拿起Python並且正在處理列表的過程。我正在使用一個測試文件,其中包含由選項卡縮進的幾行字符,然後將其傳遞到我的python程序中。 我的Python腳本的目的是將每行插入到列表中,使用長度作爲索引,這意味着列表將自動排序。我正在考慮最基本的案例,不關心任何複雜的案例。

我的python代碼如下;

newList = [] 

for line in sys.stdin: 
    data = line.strip().split('\t') 
    size = len(data) 
    newList.insert(size, data) 
for i in range(len(newList)): 
    print (newList[i]) 

我的「測試」文件在下面;

2 2 2 2 
1 
3 2 
2 3 3 3 3 
3 3 3 

我對python腳本輸出的期望是按以下順序打印列表內容:按長度排序;

['1'] 
['3', '2'] 
['3', '3', '3'] 
['2', '2', '2', '2'] 
['2', '3', '3', '3', '3'] 

但是,當我將測試文件傳遞給我的python腳本時,我得到以下內容;

cat test | ./listSort.py 
['2', '2', '2', '2'] 
['1'] 
['3', '2'] 
['3', '3', '3'] 
['2', '3', '3', '3', '3'] 

輸出['2','2','2','2']的第一行不正確。我試圖弄清楚爲什麼它沒有被打印在第四行(因爲長度爲4,這意味着它將被插入到列表的第四個索引中)。有人可以提供一些見解,爲什麼這是?我的理解是,我將'數據'作爲索引插入到列表中,這意味着當我打印出列表的內容時,它們將按照排序順序打印。

在此先感謝!

+3

嘗試重播使用筆的算法&紙張,你會明白爲什麼結果是錯誤的。 – mkrieger1

+1

還要注意「無用的貓」:'cat filename |程序「與」程序<文件名「相同。 – mkrieger1

+2

或者如果你對列表的理解是錯誤的,那麼使用筆和紙可能不會幫助你......如果你有一個長度列表* N *然後插入索引* n *> * N *將只是將它附加到列表的末尾。例如。在索引「4」處插入'x'到空列表(* N * = 0)中仍然會導致列表'[x]',而不是像[[ - , - , - , - ,x]'。 – mkrieger1

回答

3

插入到列表中的工作比你想的完全不同:

>>> newList = [] 
>>> newList.insert(4, 4) 
>>> newList 
[4] 
>>> newList.insert(1, 1) 
>>> newList 
[4, 1] 
>>> newList.insert(2, 2) 
>>> newList 
[4, 1, 2] 
>>> newList.insert(5, 5) 
>>> newList 
[4, 1, 2, 5] 
>>> newList.insert(3, 3) 
>>> newList 
[4, 1, 2, 3, 5] 
>>> newList.insert(0, 0) 
>>> newList 
[0, 4, 1, 2, 3, 5] 

希望你能看到從這個例子兩件事情:

  • 列表索引是從0開始。也就是說,第一個條目具有索引0,第二個具有索引1等。
  • list.insert(idx, val)將東西插入當前的位置具有索引idx,並且在該位置之後碰撞所有東西。如果idx大於列表的當前長度,則將新項目靜默添加到最後位置。

有實現你想要的功能幾個方面:

  1. 如果你能預測的行數,您可以事先分配列表,並簡單地分配到列表中的元素,而不是插入的:

    newList = [None] * 5 
    
    for line in sys.stdin: 
        data = line.strip().split('\t') 
        size = len(data) 
        newList[size - 1] = data 
    for i in range(len(newList)): 
        print (newList[i]) 
    

    如果你能預測一個合理的上限的行數,你也可以這樣做,但你需要有某種方式來之後刪除None條目。

  2. 使用字典:

    newList = {} 
    
    for line in sys.stdin: 
        data = line.strip().split('\t') 
        size = len(data) 
        newList[size - 1] = data 
    for i in range(len(newList)): 
        print (newList[i]) 
    
  3. 添加元素,以在必要時列表中,這可能是一點點更復雜:

    newList = [] 
    
    for line in sys.stdin: 
        data = line.strip().split('\t') 
        size = len(data) 
        if len(newList) < size: newList.extend([None] * (size - len(newList))) 
        newList[size - 1] = data 
    for i in range(len(newList)): 
        print (newList[i]) 
    
+0

非常感謝您的優秀和詳細的解釋! – Triple777er

1

我相信我已經想出了我的問題的答案,這要感謝mkrieger1。我追加到列表中,然後使用長度作爲關鍵字進行排序;

newList = [] 

for line in sys.stdin: 
    data = line.strip().split('\t') 
    newList.append(data) 
newList.sort(key=len) 
for i in range(len(newList)): 
    print (newList[i]) 

我得到了我想要的輸出;

/listSort.py < test 
['1'] 
['3', '2'] 
['3', '3', '3'] 
['2', '2', '2', '2'] 
['2', '3', '3', '3', '3'] 
+1

您不需要每次都對列表​​進行排序,只有在您添加完所有數據後才能對列表進行排序。 –

+0

是的,我不小心縮進了這種排序。編輯答案,以便在追加所有數據後進行排序。 – Triple777er