2012-08-14 74 views
1
grade=['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0] 

def convert_grades(lst): 
    a = [] 
    b = [] 
    for i in lst: 
     if isinstance(i,str): 
      c = 0 
      while lst[c] < 0 or lst[c] == []: 
       a = a + lst[c] 
       c = c + 1 
      b = b + a 
    return b 

我希望它回來作爲爲什麼我的代碼無法獲得預期的回報?

[['Ben Anderson',95,90,100],['Mary Johnson',75,78,79],['Michael Walter',80,68,0]] 

但作爲回報[]

我不知道發生了什麼事情做。需要幫助。

+2

建議:幫你調試,用'到處print'來看看怎麼回事。如果它是'[]'主要是你的一些邏輯沒有解決。這是調試問題的最簡單方法。 – User007 2012-08-14 22:00:26

+0

我會說,雖然從未執行......不知道,但 – BorrajaX 2012-08-14 22:04:06

+0

@BorrajaX是的。因爲第一個元素是「Ben Anderson」,並且它是一個字符串。第二個條件是'lst [0]'必須是一個空列表,而不是。所以它總是返回虛假:) – User007 2012-08-14 22:05:23

回答

1

嘗試這樣:

grade=['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0] 

def convert_grades(lst): 
    a = [] 
    for i in lst: 
     if isinstance(i,str): 
      a.append([])   #if a string is found than append a [] to a 
      a[-1].append(i)   #append i to the last element of a 
     elif i>=0: 
      a[-1].append(i)  #if not string then just append i to the last element of a  
    return a   

print(convert_grades(grade)) 

輸出

[['Ben Anderson', 95, 90, 100], ['Mary Johnson', 75, 78, 79], ['Michael Walter', 80, 68, 0]] 
+1

你應該解釋爲什麼他的原始代碼是錯誤的:(有一個明顯的問題,通過向他展示他的打印品 – User007 2012-08-14 22:04:00

+0

'lst [0] <0'總是假的,實際上,它是一個不好的測試 – heltonbiker 2012-08-14 22:24:31

3

我想itertools.groupby()可能是非常適用的位置:

from itertools import groupby 

def convert_grades(lst): 
    key = lambda x: isinstance(x, int) and x < 0 
    return [list(g) for k, g in groupby(lst, key) if not k] 

結果:

>>> convert_grades(['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0]) 
[['Ben Anderson', 95, 90, 100], ['Mary Johnson', 75, 78, 79], ['Michael Walter', 80, 68, 0]] 

這是通過創建一個函數key返回True當列表條目應該作爲分隔作用,並False當它不應該。通過在itertools.groupby()中使用此函數,我們可以創建所有組,然後我們只需要篩選出所得到的迭代器中的所有分隔符值。

+1

爲什麼downvote?我知道這並不完全回答「我的代碼出了什麼問題?」的問題,但提供一個替代解決方案可以幫助OP以不同的方式考慮問題。 – 2012-08-14 22:13:25

+2

downvotes *沒有*解釋沒有建設性,也沒有人幫忙 – Levon 2012-08-14 22:16:57

+2

這段代碼對於初學者來說太複雜了,Lambda ....但是一個很好的代碼 – User007 2012-08-14 22:20:04

5

輸入和輸出的相同形式的建議:原代碼的非pythonicity的

def convert_grades(lst): 
    out = [] 
    for element in grade: 
     if isinstance(element, str): 
      buf = []   # re-initializes 'buf' everytime there is a string 
      out.append(buf) 
     buf.append(element) 
    return out 

三大主要症狀:

  1. 算術運算符的用途,其中有人已經熟悉Python的成語將使用類型方法(在這種情況下爲list.append);
  2. 在列表中輸入明顯的數據類型應該是字典的輸入(儘管控制數據的方式並不總是可能的);
  3. 而且,最嚴重的症狀是,OUTPUT是實際請求字典時的列表列表。

所以,另一個更Python的方式,返回一個字典而不是列表:

def convert_grades(lst): 
    out = {} 
    for element in grade: 
     if isinstance(element, str): 
      key = element 
      out[key] = [] 
     else: 
      out[key].append(element) ## mind that this would raise an error if first element in lst is not string 
    return out 

print convert_grades(grade) 

希望這有助於!

1

另一個答案(雖然我喜歡比我更F.J's answer)和少數意見(只是建議):

#!/usr/bin/env python 

def convert_grades1(lst): 
    a = [] 
    b = [] 

    index = 0 
    while index < len(lst): 
     if isinstance(lst[index], str): 
      b.append(lst[index]) 
      index = index + 1 
      try: 
       while isinstance(lst[index], int): 
        if lst[index] > 0: 
         b.append(lst[index]) 
        index += 1 
      except IndexError: 
       print "We're done" 
      finally: 
       a.append(b) 
       b = [] 
    return a 

if __name__ == "__main__": 
    grade=['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0] 
    print convert_grades1(grade) 

1)

如果你 「行走」 的清單(或文件解析或任何...)與循環認爲如果你真的需要重新開始從一個嵌套循環開始走。在您的代碼:

for i in lst: 
    if isinstance(i,str): 
     c = 0 
     while lst[c] < 0 or lst[c] == []: 

你開始重新走在一段時間(你做c=0就在它變得之前),即使你可能已經處理它在以前塊爲「全名單通行證」。我猜你在考慮i是索引(不是,i獲取列表中的項目的值)。爲索引,可使用:for i in range(0, len(lst))for i, item in enumerate(lst)

2)

c = 0 
while lst[c] < 0 or lst[c] == []: 

在那裏,lst[c]指向列表中的(拳頭項含義中,串'Ben Anderson'),這是既不小於0也不是空列表,所以while循環永遠不會被執行。

3)

它通常被認爲是「Python化」具有以下的「更好比安全對不起」,所以不是if isinstance(i,str)你可以(在你的例子)嘗試解析一個int,如果知道你的代碼它失敗了......那麼你可以認爲它是一個字符串。

if isinstance(element, str): 
    #do stuff for string 
else: 
    #do other stuff (for int) 

可等效(你的情況):

try: 
    int(element) 
    #do other stuff (for int) 
except ValueError: 
    #do stuff for string 

要小心,因爲int("5")不會引發任何異常(即使"5"實際上是一個str)。它會給你一個int的值爲5

4)

如果你是一個初學者,print是你的朋友;)

1

只要是完整的,你可以把這個結構[str, int, int, str, int]作爲棧和左起流行結構,你希望:

grades=['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0] 
converted_list=[] 
while grades: 
    temp=[grades.pop(0)] 
    while grades and isinstance(grades[0],int): 
     temp.append(grades.pop(0)) 

    converted_list.append(temp) 

print converted_list  

打印:

[['Ben Anderson', 95, 90, 100, -1], ['Mary Johnson', 75, 78, 79, -5], ['Michael Walter', 80, 68, 0]] 

您可以使用相同的方法來創建詞典,這似乎是一個更好的數據結構:

d={} 
while grades: 
    name=grades.pop(0) 
    d[name]=[] 
    while grades and isinstance(grades[0],int): 
     d[name].append(grades.pop(0)) 

print d  

打印:

{'Mary Johnson': [75, 78, 79, -5], 'Michael Walter': [80, 68, 0], 'Ben Anderson': [95, 90, 100, -1]} 

雖然這個作品,恕我直言,F.J的答案是最 'Python化'

0

如果你想有一個理解,這個工程:

grades=['Ben Anderson',95,90,100,-1,'Mary Johnson',75,78,79,-5,'Michael Walter',80,68,0] 
eyes=[i for i, x in enumerate(grades) 
    if isinstance(x,str)]+[len(grades)+1]   # index of the strings 
LofSL=[(i,j) for i,j in zip(eyes[:-1],eyes[1:])] # slices for each list 
LoL=[grades[t[0]:t[1]] for t in LofSL]   # your list of lists 

或者,如果你想要一本字典:

DofL={grades[t[0]]:grades[t[0]+1:t[1]] for t in LofSL} 
相關問題