Python逻辑错误?

时间:2011-08-31 06:45:54

标签: python

基本上,我试图在我的函数中展平列表但忽略它(你也可以忽略我输入的打印函数)。 以x = [[1,2,3],4,5]为我的变量。 我调用prob7(x)但问题是当type([1,2,3])被检查== list时,它返回false。这是为什么?我在解释器命令行上显式检查它,它返回true。但在函数内部,我得到了一个假。

我错过了一个错误,因为我很困,或者我误解了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 :(得分: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]

答案 1 :(得分:3)

Artisom有你的答案。另外,类型检查不是非常Pythonic。 Duck typing通常是要走的路。如果您的元素只是数字,那么下面的工作也是如此,没有明确的类型检查,但行为检查:

def prob7(inlist): # flatten a list
    outlist = []
    for x in inlist:
        try:
            outlist += x
        except TypeError:
            outlist.append(x)
    return outlist

请注意,此实现中的字符串元素的行为类似于嵌套列表。无论如何,只是想说明期望行为的意义,而不是类型。

答案 2 :(得分:0)

这里的问题是您使用的是与全局list类型相同的本地变量名称(列表)。您应该更改变量名称。此外,在检查类似的类型时,您可以使用is运算符。

type(l) is list

但这是我的flatten版本。

def flatten(alist):
    rv = []
    for val in alist:
        if isinstance(val, list):
            rv.extend(flatten(val))
        else:
            rv.append(val)
    return rv

这不会改变原始列表,但会返回一个新列表。这与大多数其他模式一致。

答案 3 :(得分: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))