【问题标题】:Include empty values in a list according to specific positions (Python)根据特定位置在列表中包含空值(Python)
【发布时间】:2015-12-03 15:53:10
【问题描述】:

我有以下清单:

CompleteList=['00:00:00', '00:00:01', '00:00:02', '00:00:03',....,'23:59:59']

我还有以下列表:

IncompleteList=['00:00:00', '00:00:01', '00:00:03',....,'23:59:59']

可以看出,CompleteList 具有 IncompleteList 中缺少的值,例如值 '00:00:02'。

我还有第三个数组:

MyList=['22', '33', '25',....,'13']

我需要在 MyList 中以下列方式在 IncompleteList 缺少值的位置包含空值:

MyList_result=['22', '33','','25',....,'13']

我通过以下方式实现了这一点:

MyList_result=[]

for item in CompleteList:
    if item in IncompleteList:
        ind=IncompleteList.index(item)   
        v=MyList[ind]
        MyList_result.append(v)

    else:
        v=''
        MyList_result.append(v)

这可行,但考虑到我正在使用的列表的大小,它需要很长时间。我真的需要找到一种更有效的方法来做到这一点。任何帮助将不胜感激。

【问题讨论】:

  • 我们可以假设CompleteListIncompleteList 是排序的吗?
  • @sanchitarora:是的......我认为它们被排序为它们都包含的元素都是时间,但这会影响吗?。

标签: python list position find missing-data


【解决方案1】:

第一个直观的方法是将IncompleteList 转换为一个集合并获取MyList 的迭代器。然后它变成了迭代 CompleteList 的线性操作,如果 CompleteList 的元素存在于 IncompleteList 中,则从 MyList 迭代器中吐出下一项,否则根据您的示例为空字符串

示例代码

IncompleteList=['00:00:00', '00:00:01', '00:00:03','23:59:59']
IncompleteSet = set(IncompleteList)
MyList=['22', '33', '25','13']
CompleteList=['00:00:00', '00:00:01', '00:00:02', '00:00:03','23:59:59']
MyListIt = iter(MyList)
[next(MyListIt) if cl_elem in IncompleteSet else '' for cl_elem in CompleteList]

样本输出

Out[100]: ['22', '33', '', '25', '13']

或者,您可以压缩IncompleteListMyList 并将配对列表转换为字典。然后遍历CompleteList,如果元素存在则从字典中吐出相应的值,否则为空字符串

MyDict = dict(zip(IncompleteList, MyList))

[MyDict.get(k, '') for k in CompleteList]
Out[108]: ['22', '33', '', '25', '13']

【讨论】:

    【解决方案2】:

    你的实现的瓶颈在两个地方:

    • 您正在检查CompleteListIncompleteList 中的每个项目

      if item in IncompleteList:
      

      在最坏的情况下会扫描IncompleteListn的次数(如果nCompleteList中的元素数)

    • 如果该项目存在,您可以在以下位置找到该项目的索引

      ind = IncompleteList.index(item)
      

      这涉及对IncompleteList的另一次扫描

    @Abhijit 建议的第一个解决方案解决了第二个问题,您无需再次扫描列表即可获取索引。但是检查IncompleteList/IncompleteSet 中是否存在该项目仍然是一个瓶颈。

    如果我们可以假设已排序的列表,那么以下解决方案会更快,但会稍微复杂一些:

    MyList_result = []
    incomplete_list_index = 0
    incomplete_list_length = len(IncompleteList)
    for item in CompleteList:
        if incomplete_list_index < incomplete_list_length and IncompleteList[incomplete_list_index] == item:
            MyList_result.append(MyList[incomplete_list_index])
            incomplete_list_index += 1
        else:
            MyList_result.append('')
    

    这仅涉及CompleteList 的单次传递(并且没有预处理来生成字典作为@Abhijit 建议的第二个解决方案)。

    【讨论】:

    • @sanchitatora:我刚刚注意到这种方法有问题。显然,此方法将丢失 MyList 数组末尾的值。我的意思是我用这种方法获得的结果是: MyList_result=['22', '33', '', '25'] 而不是 ['22', '33', '', ' 25,'13']。出于某种原因,对于我包含在数组中的每个空值,我会在列表末尾少一个值。
    • @Sarah 我使用与您提供的示例输入类似的示例输入测试了该解决方案,并且它没有遗漏任何值。你可以在这里查看结果 - pastebin.com/D52jU4vH - 如果有其他人来到这里并想要测试/使用解决方案,我想解决这些问题。
    • @sanchitatora:是的,你是对的,这种方法似乎工作得很好,甚至比其他建议的方法快一点。我不知道为什么我以前遇到过这个问题。我会进一步测试它,如果我找到了我遇到这个问题的原因,我会在这里发布。
    • @sanchitatora:例如,如果我考虑以下情况,我发现了一个问题: CompleteList=['00:00:00', '00:00:01', '00:00:02 '、'00:00:03'、'23:59:59']、IncompleteList=['00:00:00'、'00:00:01'、'00:00:02'] 和 MyList=[ '22','33','25']。它说列表索引超出范围?。
    • @Sarah 已修复。我错过了一个边缘案例。
    猜你喜欢
    • 2018-10-05
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多