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]]
但它返回[]
我不知道发生了什么事。需要帮助。
答案 0 :(得分:5)
具有相同形式的输入和输出的建议:
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
前代码的非pythonicity的三个主要症状:
list.append
); 所以,这是一种更加pythonic的方式,返回字典而不是列表:
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 :(得分: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()
中使用此函数,我们可以创建所有组,然后我们只需要从生成的可迭代中过滤掉所有分隔符值。
答案 2 :(得分: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]]
答案 3 :(得分:1)
又一个答案(虽然我比{3}更喜欢我)和一些评论(只是建议):
#!/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)
它通常被认为是“pythonic”,让你的代码遵循“更好地对不起比安全”的想法,所以你可以(在你的例子中)尝试解析int而不是if isinstance(i,str)
如果它失败了......那么你可以假设它是一个字符串。
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
是您的朋友;)
答案 4 :(得分: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的回答是最“邪恶的”
答案 5 :(得分: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}