如何比较两个未知长度,顺序和重复值列表中的每个项目,同时最小化写入并保留Python中的位置?

时间:2012-10-09 22:12:33

标签: python loops

我保证我已经尝试过搜索,但我发现的每一个问题最终都会有一些未说明或违反的标准,这使得答案对我来说不够。

我正在向Python脚本发送一个列表。该列表将存储在某个地方,但我想最小化写入(这是在远程服务上,我为每次写入收费)。

listNew = ["some", "list", "sent", "in", "that", "may", "be", "different", "later", "some"]
listPrevious = ["some", "some", "list", "that", "was", "saved", "previously"]

(请不要被他们的字符串分散注意力;我的列表实际上包含整数。)

简单的基本算法是逐个索引地迭代这两个列表。如果项目相同,我不需要写;繁荣,省钱。但是,最终保存的数据应该是listNew。

在其他语言中,我可以通过索引直接引用元素。

for (int i = 0; i < listNew.length; i++) {
    // Have we exceeded the previous list's length? Time to just write data in.
    if (listPrevious[i] == null)
        listPrevious.append(listNew[i]);
        continue;

    if (listNew[i] != listPrevious[i])
        listPrevious[i] = listNew[i]
}

不幸的是,我在looping techniqueslist methods中找到的内容并未提供:

  1. 通过索引获取元素而不删除元素的方法(pop方法),

  2. 通过精确值和定位获取元素索引的方法,因为我有重复项(在上面的代码中,使用 list.index(“some”)将返回listPrevious中的第一个索引 虽然我实际上在查看listNew中的最后一个元素,也不是

  3. 在一个列表的长度之外迭代我的列表的方法(zip()似乎没有迭代超出较小列表的长度)。

  4. 关于我应该如何处理的任何想法?当我搜索之前的问题时,这三个标准中的一个总是以某种方式被违反。

    顺便说一句,我试图避免像下面这样的解决方案,这也是其他问题中标记的解决方案之一。

    for newitem in listNew
        for olditem in listPrevious
            if newitem != olditem
                # save the newitem
    

    将listNew中的元素与listPrevious中的每个元素进行比较,这是低效的。我只需要知道它是否与另一个列表中的相同索引匹配。

    -------通过评论请求

    输入:2个列表,listNew和listPrevious。另一个例子

    • listNew = [100,500,200,200,100,50,700]
    • listPrevious = [100,500,200,400,400,50]

    输出:listPrevious现在是listNew,无需覆盖相同的元素。

    listPrevious = [100,500,200,200,100,50,700]

    • 不需要写入:[100,500,200, _, ,50,_ _]&lt; - 4写保存

    • 确实需要写入:[ _, ,_ _,200,100,__,700]&lt; - 3执行写入,而不执行.length写入执行!

4 个答案:

答案 0 :(得分:3)

从你的C代码我创建了以下内容。希望它能满足您的需求:

for i in range(len(listNew)):
    # Have we exceeded the previous list's length? Time to just write data in.
    if i >= len(listPrevious):
        listPrevious.append(listNew[i])
        continue

    if listNew[i] != listPrevious[i]:
        listPrevious[i] = listNew[i]

答案 1 :(得分:2)

如果您想按顺序迭代索引,需要enumerate

for idx, item in enumerate(mylist):
  # idx is the 0-indexed value where item resides in mylist.

如果你想在python中迭代一对东西,你可以使用zip

for a, b in zip(newlist, oldlist):
  # items a and b reside at the same index in their respective parent lists.

您可以将这些方法结合起来:

for idx, (a, b) in enumerate(zip(newlist, oldlist)):
  # here you have everything you probably need, based on what I can 
  # tell from your question.

根据您的数据集,您还可以查看itertools模块中的其他功能,特别是izip_longest

答案 2 :(得分:1)

Python的列表方法实际上提供了您认为不是的所有功能(最后一个代码示例等同于您的示例代码)

  1. 通过索引获取元素而不删除它的方法(pop方法)

    >>> data = ['a', 'b', 'c']
    >>> data[1]        # accessing an element by index
    'b'
    
  2. 通过精确值和定位获取元素索引的方法,因为我有重复项(在上面的代码中,使用list.index(“some”)将返回listPrevious中的第一个索引,尽管我' m实际上是在查看listNew中的最后一个元素

    >>> data = ['a', 'b', 'c', 'b', 'a']
    >>> data.index('a')     # without a start arg, call finds the first index
    0
    >>> data.index('a', 1)  # you can find later indices by giving a start index
    4
    
  3. 迭代遍历其中一个列表长度的列表的方法(zip()不会超出较小列表的长度,似乎)。

    for i, item in enumerate(listNew):    # loops over indices and values
        if i >= len(listPrevious):
            listPrevious.append(item)
            continue
    
        if item != listPrevious[i]:
            listPrevious[i] = item
    

答案 3 :(得分:0)

项目的位置是否重要?

如果不是简单地这样做::

for n in NewList:
    if n not in OldList:
        OldList.append(n)
        process(n)