【问题标题】:Merge two list with a list of list if certain conditions are met如果满足某些条件,则将两个列表与列表列表合并
【发布时间】:2017-09-26 12:32:32
【问题描述】:

如果满足某些条件,我正在尝试合并两个列表(在列表列表中)。

一个例子:

li = [[18, 19, 20, 21, 22], [25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]

li2 = [[15, 16, 17], [32, 33, 34, 35], [89, 90, 91], [95, 96, 97, 98]]

条件是如果每个列表之间的差异(或者说是距离)小于 7 个单位,则列表将被合并。列表合并后,我想补上缺失的数字。

因此预期结果如下:

li = [[18, 19, 20, 21, 22, 23, 24, 25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]

li2 = [[15, 16, 17], [32, 33, 34, 35], [89, 90, 91, 92, 93, 94, 95, 96, 97, 98]]

这是我正在处理的当前代码:

new_li = []
for i in np.arange(len(li) - 1):
    current_item, next_item = li[i], li[i+1]

    if next_item[0] - current_item[-1] <= 7:
        new_li.append(current_item + next_item)

    else:
        new_li.append(next_item)

这给了我:

new_li = [[18, 19, 20, 21, 22, 25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]] 

并应用li2的代码:

new_li2 = [[32, 33, 34, 35], [89, 90, 91], [89, 90, 91, 92, 93, 95, 96, 97, 98]]

在我开始填写缺失值之前,我的代码是不正确的,并且似乎无法让代码的最后一部分正确。非常感谢任何改进我的代码的帮助或提示!

【问题讨论】:

  • 为什么使用np.arange? range 会更快,并且您不需要 NumPy 作为依赖项。

标签: python list


【解决方案1】:

如果已经添加了下一个列表,您需要跳过它。此外,如果当前集合不符合下一个集合的条件,您需要将当前集合添加到结果列表而不是下一个集合。

以下代码已更正:

li = [[18, 19, 20, 21, 22], [25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]
li2 = [[15, 16, 17], [32, 33, 34, 35], [89, 90, 91], [95, 96, 97, 98]]

new_li = []
for i in range(len(li2) - 1):
    current_item, next_item = li2[i], li2[i+1]

    if next_item[0] - current_item[-1] <= 7:
        new_li.append(current_item + next_item)
        i+=1
    else:
        new_li.append(current_item)


for item in new_li:
    print (item)

【讨论】:

    【解决方案2】:

    对于此类任务,我更喜欢生成器函数(例如参见 "What does the “yield” keyword do?"),因为您可以轻松地在循环中使用它们(无需创建完整列表)并在必要时将它们转换为列表(或其他容器) .

    基本上这将满足您的要求:

    def merge(li):
        current = None
        for sublist in li:
            if current is None:
                # First iteration, just set the "current" then process the next sublist.
                current = sublist
                continue
            if sublist[0] - current[-1] <= 7:
                # first append the missing values
                current.extend(range(current[-1] + 1, sublist[0]))
                # then append the next sublist
                current.extend(sublist)
            else:
                # Difference is greater than 7 yield the current list and then reset it.
                yield current
                current = sublist
        # Exhausted, yield the last current then exit.
        yield current
    

    这为您的案例提供了预期结果(请注意,它需要在生成器函数调用周围使用 list()):

    >>> list(merge([[18, 19, 20, 21, 22], [25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]))
    [[18, 19, 20, 21, 22, 23, 24, 25, 26, 27], [59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]]
    
    >>> list(merge([[15, 16, 17], [32, 33, 34, 35], [89, 90, 91], [95, 96, 97, 98]]))
    [[15, 16, 17], [32, 33, 34, 35], [89, 90, 91, 92, 93, 94, 95, 96, 97, 98]]
    

    它还可以合并几个子列表,这对你来说是个问题:

    >>> list(merge([[1,2], [5, 6], [10,11], [200]))
    [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [200]]
    

    【讨论】:

      【解决方案3】:

      您可以按照以下方式进行:

      def merge(li):
        return [li[i] + range(max(li[i]) + 1, min(li[i+1])) + li[i+1] 
                if min(li[i+1]) - max(li[i])<7 
                else li[i] for i in range(len(li)-1)]
      

      由于列表已排序,您可以将max(list_name) 替换为list_name[-1],将min(list_name) 替换为list_name[0]。因此,您可以将解决方案重写如下:

       def merge(li):
           return [li[i] + range(li[i][-1]+1, li[i+1][0]) + li[i+1] 
                    if li[i+1][0] - li[i][-1] <7 
                    else li[i] for i in range(len(li)-1)]
      

      执行细节:

      In [94]: def merge(li):
          ...:     return [li[i]+range(max(li[i])+1, min(li[i+1]))+li[i+1] 
                   if min(li[i+1])-max(li[i])<7 
                   else li[i] for i in range(len(li)-1)]
          ...: 
          ...: 
      
      In [95]: merge(li)
      Out[95]: [[18, 19, 20, 21, 22, 23, 24, 25, 26, 27], [25, 26, 27]]
      
      In [96]: merge(li2)
      Out[96]: [[15, 16, 17], [32, 33, 34, 35], [89, 90, 91, 92, 93, 94, 95, 96, 97, 98]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-24
        • 2018-07-14
        • 2020-01-22
        • 2020-06-27
        • 1970-01-01
        • 2015-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多