【问题标题】:Am I doing this right? Removing items from python list - is there room for optimization?我这样做对吗?从 python 列表中删除项目 - 是否有优化空间?
【发布时间】:2017-05-25 11:49:43
【问题描述】:

我有 2 个列表。我想从列表中删除所有包含第二个列表中的字符串的项目。现在,我使用经典的 2 循环方法,第一个循环遍历主列表的副本,然后对于每个项目,我检查它是否包含来自第二个列表的任何字符串。然后,如果找到字符串,我将删除该项目。我可以用 break 结束第二个循环,因为不再需要查找(无论如何我们都会删除这一行)。这工作得很好 - 正如你所看到的,我正在迭代列表的副本,所以删除元素不是问题。

代码如下:

    intRemoved = 0

    sublen = len(mylist) + 1
    halflen = sublen / 2

    for i, line in enumerate(mylist[:], 1):
        for item in REM:
            if item.encode('utf8').upper() in line.text.encode('utf8').upper():
                if i < halflen:
                    linepos = i
                else:
                    linepos = (sublen - i) * -1

                mylist.remove(line)
                intRemoved += 1
                break

现在,我需要数据我删除了多少行 (intRemoved) 和在列表中的位置(从列表的开头或列表的结尾,这就是它分成两半的原因)。正数表示从文件开头删除的行位置,负数表示从末尾开始。

啊,是的,我忽略了这个案子。这就是为什么有 .upper()。

现在,由于我绝不是专业人士,我只需要知道我是否做得对,就性能而言?我在做对性能不利的事情吗?有没有办法优化这个?

谢谢, D.

【问题讨论】:

  • 询问优化问题的最佳地点是 codereview.stackexchange
  • 我的建议:在比较之前标准化列表(大写)。排序也有帮助,不确定。
  • (1) linepos 似乎已计算但从未使用过 (2) break 表示为时过早 (3) 在考虑优化之前让它工作!
  • 我在后面的代码中使用它,但与本案无关
  • (1) linepos 似乎已计算但从未使用过。 (2)subSrt是什么? (3) 在考虑优化之前让它工作!

标签: python list optimization


【解决方案1】:

正如您所说,您可能应该查看 codereview。无论如何,我很确定使用setsintersection 操作会快得多。

看这里:https://docs.python.org/2/library/stdtypes.html#set

【讨论】:

  • 谢谢你的链接,很高兴学到一些东西。但从我读过的内容来看,我不确定在这种情况下集合是否适合使用 - 我在两个列表中没有相同的元素,我正在寻找 list2 包含的 list1 中元素的任何部分,即list1 "这是一个例子" list2 "是一个"...
  • matching_words = [(index, string1, string2) for number,string1 in enumerate(a, 1) for string2 in b if ((string1.upper() in string2.upper()) or (string2.upper() in string.upper()))]
  • 试试看。如果您有两个由字符串组成的列表a,b,则 sn-p 足以找到常见的出现并以[index (in list1), ocurrence, ocurrence] 的形式将它们返回给您
【解决方案2】:

无需致电encode。每次调用upper 并不理想。处理列表进行迭代是昂贵的。删除更昂贵,因为必须搜索元素和移动元素。数intRemoved 也不是最好的方法。

sublen = len(subsSrt) + 1
halflen = sublen / 2
filtered_list = []
rem_upper = [item.upper() for item in REM]
for i, line in enumerate(mylist, 1):
    text = line.text.upper()
    if any(item in text for item in rem_upper):
        if i < halflen:
            linepos = i
        else:
            linepos = (sublen - i) * -1
    else:
        filtered_list.append(line)
intRemoved = len(mylist) - len(filtered_list)

【讨论】:

  • 你不是说:rem_upper = [item.upper() for item in REM] 带括号吗?
  • 酷,thanx,我刚刚测试过,处理时间从 1.27 秒变为 0.24....只有一件事 - 有没有办法知道在 rem_upper 中找到了哪个项目?在我的旧代码中,我会使用“item”....
  • 如果你需要item,你应该使用第二个循环。
猜你喜欢
  • 2011-01-17
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多