2017-10-12 69 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