我正在读取一个字符串列表,每个字符串都与一个文件名相关。但是,每个字符串都是减去扩展名。我想出了以下代码:
import re
item_list = ['item1', 'item2']
search_list = ['item1.exe', 'item2.pdf']
matches = []
for item in item_list:
# Match item in search_list using re - I assume this is the best way to do this
regex = re.compile("^"+item+"\.")
for file in search_list:
if regex.match(file):
matches.append((item, file))
至于重复的匹配,我并不十分担心两个文件被命名为'foo.bar'和'foo.foo.bar'。话虽这么说,还有更好的方法吗?
谢谢。
答案 0 :(得分:2)
您可以将所有项目组合成一个像这样的效率更高效的正则表达式
import re
item_list = ['item1', 'item2']
regex = re.compile("^("+"|".join(item_list)+")\.")
search_list = ['item1.exe', 'item2.pdf']
matches = []
for file in search_list:
match = regex.match(file)
if match:
matches.append((match.group(1), file))
更好的解决方案可能是使用os.path函数解析文件名,但要解析出基本名称并在集合中查找它们。
答案 1 :(得分:2)
使用splitext获取不带扩展名的文件名:
import os.path
for item in item_list:
for filename in search_list:
if item == os.path.splitext(filename)[0]:
matches.append((item, file))
这更正确,但通过阅读代码也更容易理解你的意图。或者,如果你想允许foo匹配foo.bar.txt,那么请改用filename.startswith(item +'。')。
答案 2 :(得分:1)
您不需要使用正则表达式,因为您正在进行精确的字符串匹配(没有通配符,组等) - 您可以使用 str.startswith(..)。这相当于您的代码:
for item in item_list:
match = item + "."
for file in search_list:
if file.startswith(match)
matches.append((item, file))
然而尼克克雷格 - 伍德关于将所有比赛编译成单个正则表达式的建议可能会更有效率 - 我建议你在速度是一个问题的基础上进行基准测试。
答案 3 :(得分:1)
除非你真的需要,否则请避免使用re
。对于简单的字符串匹配,您根本不需要它。
Mark Byers的回答重复了将matches
保留在item_list
订单中的原始行为。如果你不需要,你可以更简单/更快地完成它:
for file in search_list:
item= os.path.splitext(file)[0]
if item in item_list:
matches.append((item, file))
如果您不需要保持(item)
匹配(因为它仍然是文件名中的冗余),您就有了一个单行:
matches= [file for file in search_list if os.path.splitext(file)[0] in item_list]
答案 4 :(得分:0)
这是另一种方法,它可能比Alex的原始代码更快:
item_list = ['item1', 'item2']
search_list = ['item1.exe', 'item2.pdf']
matches = []
for item in item_list:
for filename in search_list:
if filename.partition(".")[0] == item:
matches.append((item,filename))
答案 5 :(得分:0)
我认为你应该使用.rsplit(".",1)
来实现这个目的,正则表达式是不是有点过分了?
>>> item_list = ['item1', 'item2','item3']
>>> search_list = ['item1.exe', 'item2.pdf','item9999.txt']
>>>
>>> [(x.rsplit(".",1)[0],x) for x in search_list if x.rsplit(".",1)[0] in item_list]
[('item1', 'item1.exe'), ('item2', 'item2.pdf')]
或for for循环
matches=[]
for x in search_list:
y=x.rsplit(".",1)[0]
if y in item_list:
matches.append((y,x))
答案 6 :(得分:0)
>>> for file in search_list:
... tomatch=file.split(".")[0]
... if tomatch in item_list:
... found=item_list.index(tomatch)
... matches.append( ( file, item_list[found] ) )
...
>>> print matches
[('item1.exe', 'item1'), ('item2.pdf', 'item2')]
>>>
不需要正则表达式。