【问题标题】:Why does list turn out different than expected?为什么列表结果与预期不同?
【发布时间】:2020-04-07 08:36:21
【问题描述】:

我有一个整数列表。然后我想更改列表,以便它不包含,比如说连续四个 1:s,它应该说[[4, 1]]。所以我为此做了一个函数,但我得到了一个意想不到的结果。

这是函数

compressed3 = []

def repeat_comp(data):
    rep = 1

    for i, item in enumerate(data):
        if i < len(data) - 1:
            if item == data[i + 1]:
                rep += 1

            else:
                compressed3.append([rep, data[i - 1]])
                rep = 1

        else:
            if item == data[i - 1]:
                rep += 1

            else:
                compressed3.append([rep, data[i - 1]])
                rep = 1

repeat_comp(compressed2)

这是compressed2 列表

[0,
 1,
 2,
 3,
 1,
 1,
 1,
 1,
 4]

这是函数的结果与预期结果的比较

# output of function
[[1, 2832], # why this? (this number is one less than the lenght of another list that has nothing with this list to do)
 [1, 0],
 [1, 1],
 [1, 2],
# excluded value here
 [4, 1],
 [1, 1], # why this?
 [1, 4]]

# expected result
[[1, 0],
 [1, 1],
 [1, 2],
 [1, 3],
 [4, 1],
 [1, 4]]

【问题讨论】:

    标签: python python-3.x list function compression


    【解决方案1】:

    您只需要更改代码中的两件事即可获得预期的结果:

    def repeat_comp(data):
        rep = 1
        compressed3 = []
    
        for i, item in enumerate(data):
            if i < len(data) - 1:
                if item == data[i + 1]:
                    rep += 1
    
                else:
                    compressed3.append([rep, item])
                    rep = 1
    
            else:
                if item == data[i - 1]:
                    rep += 1
    
                else:
                    compressed3.append([rep, item])
                    rep = 1
        return compressed3
    

    compressed3 列表移动到函数中并让函数返回它,因此每次调用函数compressed3 都会被清除。然后,您可以将返回的列表分配给另一个变量:

    result = repeat_comp(compressed2)
    

    我把data[i - 1]改成了item

    print(result) 会给你[[1, 0], [1, 1], [1, 2], [1, 3], [4, 1], [1, 4]]

    【讨论】:

      【解决方案2】:

      这很好地说明了为什么函数应该是idempotent,也就是说,在给定相同输入的情况下,函数的每次调用都应该产生相同的结果。通过将结果列表compressed3 移到函数之外,调用者需要确定哪些调用会改变这个全局变量;几乎不可避免地会出现令人困惑的结果。

      我会编写如下函数,使用itertools.groupby:

      from itertools import groupby
      
      def compress_runs(lst):
          return [[len(list(v)), k] for k, v in groupby(lst)]
      
      if __name__ == "__main__":
          print(compress_runs([1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6])) 
          # => [[3, 1], [2, 2], [2, 3], [1, 4], [2, 5], [1, 6]]
      

      【讨论】:

        猜你喜欢
        • 2015-09-14
        • 2023-02-02
        • 1970-01-01
        • 2020-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-12
        相关资源
        最近更新 更多