Python逻辑错误?
基本上,我在我的函数里想把一个列表变得扁平化,但你可以忽略这个(你也可以忽略我放的打印函数)。
假设 x = [[1,2,3],4,5]
是我的变量。
我调用 prob7(x)
,但问题是当我检查 type([1,2,3])
时,它返回的结果是 false。为什么会这样?我在命令行里明确检查过,返回的是 true。但是在函数内部,我却得到了 false。
这是我因为困而错过的一个bug,还是我对Python语言的某个部分理解错了?我用的是2.6版本,如果这有关系的话。
def prob7(list): # flatten a list
tempList = []
if list: # meaning if there are elements in the list and it is not empty
for i in list:
if type(i) != list:
print tempList,'if',i,type(i)==list
tempList.append(i)
else:
print tempList,'else',i
tempList.extend(prob7(i))
return tempList
4 个回答
0
一些其他的方法:
# Iterative, but more functional-style
def flatten(a_list):
while any(isinstance(x, list) for x in a_list):
a_list = sum((x if isinstance(x, list) else [x] for x in a_list), [])
return a_list
# Using a generator recursively,
# then evaluating the generator to produce the list
# instead of explicitly appending each element.
def flatten_gen(a_list):
for x in a_list:
if isinstance(x, list):
for y in flatten_gen(x): yield y
else: yield x
def flatten(a_list): return list(flatten_gen(a_list))
3
Artisom 给出了答案。此外,类型检查在 Python 中并不是很“Pythonic”。鸭子类型通常是更好的选择。如果你的元素只有数字,下面的代码也能完成任务,不需要明确的类型检查,而是检查行为:
def prob7(inlist): # flatten a list
outlist = []
for x in inlist:
try:
outlist += x
except TypeError:
outlist.append(x)
return outlist
请注意,这个实现中的字符串元素会像嵌套列表一样工作。总之,我只是想说明一下,期待行为而不是类型的意义。
3
不要把'list'当作变量名来用,应该用isinstance(var, list)来检查变量是不是列表,而不是用type(var) == list。下面是修正后的示例。
def prob7(mylist): # flatten a list
tempList = []
if mylist: # meaning if there are elements in the list and it is not empty
for i in mylist:
if not isinstance(i, list):
print tempList, 'if', i, isinstance(i, list)
tempList.append(i)
else:
print tempList, 'else', i
tempList.extend(prob7(i))
return tempList
或者,如果你不一定要用递归,而且对值的顺序也不在乎的话,你可以用下面这种方式:
lVals = [[1,2,3],4,5, [1,[4,7]]]
def make_flat(mylist): # flatten a list
while any(isinstance(x, list) for x in mylist):
for i, val in enumerate(mylist):
if isinstance(val, list):
mylist.extend(mylist.pop(i))
break
return mylist
make_flat(lVals)
>>> [4, 5, 1, 2, 3, 1, 4, 7]