繁体   English   中英

从python中的列表中删除多个重复值

[英]remove multiple repeating values from list in python

我正在处理由报表软件生成的大(〜5000行)文本文件。 这些文件每页有多个标题行,并且在整个过程中都有许多空行。 我已经找到了一种过滤掉不需要的数据的方法,但是我想知道这是否是实现此目的的最佳方法。 我有用于过滤列表的此函数,它基本上是遍历列表并通过每次删除其中一条过滤器行来减少列表。

def process_block(b):
    b1 = [line for line in b if not line.startswith('100   V')]
    b2 = [line for line in b1 if not line.startswith('300   V')]
    b3 = [line for line in b2 if not line.startswith('400   V')]
    b4 = [line for line in b3 if not line.startswith('AR00000')]
    b5 = [line for line in b4 if not line.startswith('734 - C')]
    b6 = [line for line in b5 if not line.lstrip().startswith('TXN DAT')]
    b7 = [line for line in b6 if not line.startswith('   ACCO')]
    b8 = [line for line in b7 if not line.rstrip() == '']
    return b8

我觉得自己做的传球次数超过了必要。 有没有更好的方法来完成此过滤?

str.startswith()方法接受一个前缀元组。 因此,您可以使用一个列表推导,而不是多个循环,并将所有模式传递给一个startswith()方法。

而且,您可以使用以下生成器函数以更Python化的方式从文件中返回经过迭代器过滤的对象:

def filter(file_name):
    prefixes = ("100   V", "300   V", "400   V",...)
    with open(file_name) as f:
        for line in f:
            if not line.lstrip().startswith(prefixes):
                yield line

如果您不考虑内存使用,则可以使用列表推导将文件对象过滤掉,这是一种更快的方法。

filtered_obj = [line for line in file_object if not line.lstrip().startswith(prefixes)]

您绝对可以一口气做到这一点。


def process_block(b)
    return [line for line in b if  
        not line.startswith(
                ('100   V', '300   V', '400   V', 'AR00000', '734 - C', '   ACCO')
            )
        and not line.lstrip().startswith('TXN DAT')
        and not line.rstrip() == ''] 

您可能会发现以下方法很有用:

鉴于:

a = ['test', 'test_1', 'test_2', 'test_3', 'test']

b = ['test']

我们可以减去ba如下:

c = list(set(a) - set(b))

print(c)

产生:

['test_3', 'test_2', 'test_1']

或者我们可以按以下方式删除重复项:

c = list(dict(zip(a, [None]*len(a))).keys())

print(c)

产生:

['test_3', 'test_2', 'test', 'test_1']

请注意,在后一种方法中,订单丢失。 如果您希望保留订单,请使用Python本机库中的collections.OrderedDict

现在只需要拆分字符串并对其进行操作即可。

将您的模式放在列表中,然后您可以否决任何给定的行

patterns = ['aaa' , 'bbb']
any(line.startswith(p) for p in patterns)

要处理整个文件,请使用filter构建迭代器

for line in filter(lambda l: not any(l.startswith(p) for p in patterns), fp):
    print(line)

str.startswith可以接受元组而不是字符串:

return [line for line in b if not line.startswith(
    '100   V', '300   V', '400   V', 'AR00000', '734 - C', '   ACCO'
    ) and not line.lstrip().startswith('TXN DATE') and line.rstrip() != '']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM