比较元组列表中的多个项目并从同一列表中删除元组

时间:2017-08-25 13:47:38

标签: python python-3.x tuples

目前我正在用Python分析字幕,所以我下载了一堆字幕,但大多数系列都有同一集的多个SRT文件。我想删除重复项,因此我编写了一个正则表达式,它产生一个列表(re_results),我用','。join(map(str,re_finds))格式化,所以我得到一个string作为我的list元素,仅包含每个文件的系列名称,季节和剧集。这将使我能够扫描类似的字符串,然后是字幕副本。

>>> re_duplicate = re.compile(r'^(.+)\s*-{1}\s*(\d+)x{1}(\d+)\s*-.*$')
>>> test_string = "CSI - 11x01 - Shock Waves.HDTV.FQM.en.srt"
>>> re_duplicate.findall(test_string)[0]
('CSI ', '11', '01')
>>> ','.join(map(str, re_duplicate.findall(test_string)[0]))
'CSI ,11,01'

(字符串看起来并不重要,只要它标识名称,季节和剧集编号。) 由于我只对该系列的实际演讲感兴趣,我只想保留最小的文件。原因是较小的文件很可能不包括我获得副标题的链接,创建者,聋人的帮助(“[听到脚步声接近]”,这不是语音)等等。

实际问题: 为了比较我创建了以下元组列表的文件:“subtitle_tuple_list”

模式:[('正则表达式输出为字符串','文件包含文件名的路径',文件大小),...]

[('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.FQM.en.srt', 53340), 
('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.LOL.en.srt', 52059), 
('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.en.srt', 62697), 
('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.LOL.en.srt', 61159), …]

我现在想做什么(但不能): 浏览列表并比较正则表达式输出,对于每个相同的字符串比较文件大小,使用路径和文件名删除除最小值之外的所有字符串。

我知道一种方法是使用以下方法获取第一个元组的正则表达式输出:

[item[0] for item in subtitle_tuple_list]

然后我必须在下一个元组中查找正则表达式输出,如果它们匹配比较文件大小,则从元组列表中删除较大文件的条目。如果两者的大小相同,则保留第一个。将即将删除的文件保留在单独的列表中。 这样做直到你得到一个新的正则表达式输出,这是一个不同的插曲。 重复直到每个剧集只剩下一个文件,这意味着新列表现在包含要删除的所有文件。 删除该列表中提到的所有文件。

我不知道如何写这部分。

另外一个问题:有没有更好的方法来删除不需要的字幕文件?

3 个答案:

答案 0 :(得分:1)

要根据需要过滤列表,您可以使用pandas:

>>> data = [('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.FQM.en.srt', 53340), ('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.LOL.en.srt', 52059), ('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.en.srt', 62697), ('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.LOL.en.srt', 61159)]

>>> import pandas as pd
>>> df = pd.DataFrame(data)
>>> df = df.groupby(0).min()
>>> df

                                                           1      2
0                                                                  
CSI ,1,01  path_to_file\CSI - 11x01 - Shock Waves.HDTV.FQ...  52059
CSI ,1,02  path_to_file\CSI - 11x02 - Pool Shark.HDTV.LOL...  61159

将其转换回列表:

df.values.tolist()

答案 1 :(得分:1)

您可以使用defaultdict按列表中的正则表达式收集所有文件。然后按文件大小排序列表:

from collections import defaultdict

data = [('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.FQM.en.srt', 53340), 
('CSI ,1,01', 'path_to_file\CSI - 11x01 - Shock Waves.HDTV.LOL.en.srt', 52059), 
('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.en.srt', 62697), 
('CSI ,1,02', 'path_to_file\CSI - 11x02 - Pool Shark.HDTV.LOL.en.srt', 61159)]

dic = defaultdict(list)

for (reg, file, size) in data:
    dic[reg].append((file, size))

for key in dic:
    item=dic[key]
    item.sort(key=lambda t:t[1])
    print(item[0])

输出:

('path_to_file\\CSI - 11x01 - Shock Waves.HDTV.LOL.en.srt', 52059)
('path_to_file\\CSI - 11x02 - Pool Shark.HDTV.LOL.en.srt', 61159)

答案 2 :(得分:0)

所以让我做对了。你有很多CSI的SRT。并且你想安排它,使每个CSI剧集有一个 SRT。

所有文件都在同一目录中吗?更好的是还可以将样本文件放在git repo上看看?因为解决方案存在很多变化,具体取决于它们的排列方式和内容。