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

时间:2016-02-18 18:36:53

标签: python

我正在处理由报告软件生成的大型(~5000行)文本文件。这些文件每页有多个标题行,并且包含许多空白行。我已经想出了一种过滤掉我不需要的数据的方法,但我想知道这是否是最好的方法。我有这个功能,我用来过滤列表,它基本上迭代列表,并通过每次删除一个过滤行来减少它。

var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

if (devices.Count > 0)
            {
                if (devices.Count >= 2)
                {
                    var device = devices.FirstOrDefault(d => d.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front);
                }
            }


var frontVideoId = device.Id;
await mc.InitializeAsync(new MediaCaptureInitializationSettings
            {
            MediaCategory = MediaCategory.Communications,
            StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
            VideoDeviceId = frontVideoId
            });
CaptureElement.Source = mc;
await mc.StartPreviewAsync();

我觉得我做的次数超过了必要的次数。是否有更好的方法来完成此过滤?

5 个答案:

答案 0 :(得分:0)

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

作为一种更加pythonic的方式,您可以使用以下生成器函数从文件中返回迭代器过滤的对象:

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)]

答案 1 :(得分:0)

你绝对可以一次性完成。


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() == ''] 

答案 2 :(得分:0)

您可能会发现这些方法很有用:

鉴于:

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

b = ['test']

我们可以从b中减去a,如下所示:

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

现在只需要拆分你的琴弦并操纵它们。

答案 3 :(得分:0)

将您的模式放在一个列表中,然后您可以使用

否决任何给定的行
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)

答案 4 :(得分:-1)

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() != '']