Python逻辑错误?

2 投票
4 回答
1759 浏览
提问于 2025-04-17 00:50

基本上,我在我的函数里想把一个列表变得扁平化,但你可以忽略这个(你也可以忽略我放的打印函数)。

假设 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]

撰写回答