Python:仅在列表末尾删除重复的值

时间:2015-10-08 17:28:37

标签: python list nan

我有一个python列表,其中响应的顺序很重要。我想过滤掉masterWKB.masterWKS.Cells(lastLineWKB, 1).PasteSpecial 值,只要它们出现在列表的末尾。我想知道是否有一种高效的方式可以从以下列表中找到:

nan

到没有任何尾随nan = float("nan") responses = [1.0, nan, 9.0, nan, nan, nan, nan, nan, nan, nan, nan] 值的列表:

nan

我知道如何使用列表解析过滤掉所有[1.0, nan, 9.0]值:

nan

但是不能想到一种直接的方法来在最后过滤掉import pandas as pd [r for r in responses if pd.notnull(r)] >>> [1.0, 9.0] 值而不将所有内容都转换为字符串并使用正则表达式。我可以做到这一点,但我担心性能,这是一个问题,因为它将执行数十万次。

4 个答案:

答案 0 :(得分:2)

while responses and math.isnan(responses[-1]):
    responses.pop()

更新:这并不像直线切片一样快。

>>> timeit.timeit('responses = list(r)\nwhile responses and isnan(responses[-1]): responses.pop()', 'from math import isnan; nan = float("nan"); r = [1.0, nan, 9.0, nan, nan, nan, nan, nan, nan, nan, nan]')
1.3209394318982959
>>> timeit.timeit('responses = list(r)\nresponses = responses[:3]', 'from math import isnan; nan = float("nan"); r = [1.0, nan, 9.0, nan, nan, nan, nan, nan, nan, nan, nan]')
0.29652016144245863

答案 1 :(得分:1)

没有内置函数或方法。但你可以使用一个循环:

while responses and math.isnan(responses[-1]):
    del responses[-1]

正如你自己所看到的,这是以线性时间运行的,不会占用额外的空间。

答案 2 :(得分:0)

您可以撤消它并使用itertools.dropwhile。这应该适用于任何价值。

r = [1.0, nan, 9.0, nan, nan, nan, nan, nan, nan, nan, nan]
list(itertools.dropwhile(lambda x: x == r[-1], reversed(r)))[::-1] + r[-1:]

要仅过滤nan,您可以将lambda x: x == r[-1]替换为math.isnan

list(itertools.dropwhile(math.isnan, reversed(r)))[::-1]

答案 3 :(得分:0)

我要做的是迭代列表一次,然后找到nans的结束序列开始的位置。像

这样的东西
responses = [1.0, 'nan', 9.0, 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan', 'nan']

first_index = -1
for i, val in enumerate(responses):
  if val == 'nan':
    if first_index == -1:
      first_index = i
  else:
    first_index = -1

responses = responses[:first_index]  # [1.0, 'nan', 9.0]

然后您可以执行单个切片操作。它比其他解决方案更冗长,但应该更快。

时间复杂性

根据to this page,切片操作为O(n),并且在列表上迭代为O(n),使得整个算法O(n)复杂。

更好的方法是向后迭代列表。