当我认为这是一个列表时,为什么这个对象被视为整数?

时间:2018-01-26 13:51:41

标签: python

这是一个练习题,内容如下:

定义一个过程,该过程接收1-9中的一串数字,并输出一个包含以下参数的列表:

  1. 字符串中的每个数字都应插入列表中。

  2. 如果字符串中的数字x小于或等于前面的数字     数字y,应将数字x插入子列表中。继续     将以下数字添加到子列表中,直到达到一个数字     z大于数字y。然后将此数字z添加到     正常列表并继续。

  3. 示例:

    string = '543987'; result = [5,[4,3],9,[8,7]]
    
    string= '987654321'; result = [9,[8,7,6,5,4,3,2,1]]
    
    string = '455532123266'; result = [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
    
    string = '123456789'; result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    我的代码如下:

    def numbers_in_lists(s):
        n=len(s)
        p=[]
        i=0
        while i<=n-1:
            p.append(int(s[i]))
            i=i+1
    
        r=[p[0]]    
        if p[1]<=p[0]:
            r.append([p[1]])
        else:
            r.append(p[1])
        if n<=2:
            return r
        j=2
        while j<=n-1:
            if p[j]<=p[j-1]:
                if p[j-1]<=p[j-2]:
                    r[-1].append(p[j])
                else:
                    r.append(p[j])
            else:
                if p[j]<=p[j-2]:
                    r[-1].append(p[j])
                else:
                    r.append(p[j])
            j=j+1
        return r
    

    当我试图运行print (numbers_in_lists('543987'))时,我得到了这个:

    Traceback (most recent call last):
      File "Lesson14Quiz3.py", line 33, in <module>
        print (numbers_in_lists(string))
      File "Lesson14Quiz3.py", line 20, in numbers_in_lists
        r[-1].append(p[j])
    AttributeError: 'int' object has no attribute 'append'
    

    问题似乎在于这一行:r[-1].append(p[j])。但我认为,当满足前面的条件时,r[-1]不应该是整数,而应该是列表。

2 个答案:

答案 0 :(得分:4)

这行代码:

r[len(r)-1].append(p[j])

分解为:

r: your overall list
len(r): an integer value based on calculation of the length of r 
-1: also an integer value

让我们假装len(r)为5。

因此5 - 1等于4.

r[4]使用Python索引来标识列表r中的特定元素。具体而言,位于第4位的元素,从索引0开始计数。

如果位置4的元素是一个整数(而不是子列表),那么Python就不能在数字上附加任何内容,因为数字没有.append()方法。

实施例

假设我们有一个类似的列表:

r = [7, 13, 42] 

我们想追加99。

>>> r.append(99)
[7, 13, 42, 99]

但如果我们索引到r中的一个整数,而不是r中的子列表,我们就会收到错误。

>>> r[1].append(99)     # r[1] is the value 13.
AttributeError: 'int' object has no attribute 'append'

最后,如果我们要编入索引的项目是子列表,那么append()就可以正常工作。

# presume r now equals: [7, 13, 42, 99, [1]]
#    and we want to append a 1337
>>> r[-1].append(1337)     # r[-1] is the last value and is a sublist
[7, 13, 42, 99, [1, 1337]]

可能的解决方案:

这可能有助于解决您的问题,并可能更容易对代码进行问题排查。

def numbers_in_lists(s):
    # use a list comprehension to simplify the process of making a list of
    #     integers
    p = [int(x) for x in s]

    # set two sentinel values to help control the code logic/decisions
    flag = False
    previous_high = 0

    # create an empty list
    r = []

    # iterate over all the digits...
    for num in p:

        # the code logic is broken into three tests 
        if num <= previous_high and not flag:
            # if flag is False create a sublist
            r.append([num])
            flag = True

        elif num < previous_high and flag:
            # if flag is True append to a sublist we previously created
            r[-1].append(num) 

        elif num > previous_high:
            # Otherwise, append to the main list again   
            r.append(num)
            previous_high = num
            flag = False

    return r

示例输出(使用OP提供的字符串):

>>> numbers_in_list('543987')
[5, [4, 3], 9, [8, 7]]

>>> numbers_in_list('987654321')
[9, [8, 7, 6, 5, 4, 3, 2, 1]]

>>> numbers_in_list('455532123266')
[4, 5, [5, 3, 2, 1, 2, 3, 2], 6, [6]]

>>> numbers_in_list('123456789')
[1, 2, 3, 4, 5, 6, 7, 8, 9]

答案 1 :(得分:4)

r是一个列表。所以,你可以放心地r.append(p[1])。但r[len(r)-1]是位置r中列表len(r)-1中的一个元素,它是一个整数,而不是一个列表。 r[len(r)-1].append(p[j])正在append上执行int,这是不可能的。因此这个错误。

例如: 考虑r = [ 1, 2, 3, 4, 5]

>>> r.append(6)
 [1, 2, 3, 4, 5, 6]

>>> r[5].append(7) # here r[5] is 6 which is an integer
AttributeError: 'int' object has no attribute 'append'

使用您的代码,输入s ='4655....'会显示此错误。由于您附加了4,因此您会看到6更大,因此您将其添加为下一个元素。然后你会看到5。您的代码会将其添加为元素。然后再来一个5以下是问题。在该步骤,p[j]<=p[j-1](5 <= 5)和p[j-1]<=p[j-2](5 <= 6)为真。因此,r[-1].append(p[j])r[-1]5的地方完成(在5上附加操作实际上是整数)。

请遍历您的代码。存在逻辑错误,导致追加到integer

两个问题:

问题1:在您的代码中,while j<=n-1:循环内,您没有在列表r中创建任何子列表。当p[j]<=p[j-1]为真且p[j-1]<=p[j-2]为false时,实际上您需要创建一个包含项p[j]的子列表。您改为将p[j]添加为列表中的元素。

问题2:您的代码仅检查列表中的最后三个元素。这会导致新项目在列表中作为新元素插入时,它实际上应该是子列表中的元素。

<强> SOLUTION:

def numbers_in_lists(s):
    n=len(s)
    p=[]
    i=0
    while i<=n-1:
        p.append(int(s[i]))
        i=i+1

    r=[p[0]]    
    if p[1]<=p[0]:
        r.append([p[1]])
        k = p[1]
    else:
        r.append(p[1])
        k = -1
    if n<=2:
        return r
    j=2
    while j<=n-1:
        if p[j]<=p[j-1]:
            if p[j-1]<=p[j-2] or p[j]<=k:
                r[-1].append(p[j])
            else:
                r.append([p[j]])
                k = p[j]
        else:
            if p[j]<=p[j-2] or p[j]<=k:
                r[-1].append(p[j])
            else:
                r.append(p[j])
        j=j+1
    return r

<强>输出:

'543987' ->  [5, [4, 3], 9, [8, 7]]

'987654321' ->  [9, [8, 7, 6, 5, 4, 3, 2, 1]]

'455532123266'  ->  [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]

'123456789'  ->  [1, 2, 3, 4, 5, 6, 7, 8, 9]