这个问题是关于将一个列表中的字符串与匹配的字符串进行匹配 在另一个列表中。我试图找出进行这种匹配的最佳方法。我下面的示例很小,但是我必须将同样的想法应用到更大的列表中。所以我在一个列表中有一组文件名和路径, 然后在另一个列表中有一个部分文件名列表, 例如:
list1 = ['/../../abc_file1.txt',
'/../../abc_extrafile1.txt',
'/../../abc_file2.txt',
'/../../abc_file3.txt',
'/../../abc_extrafile3.txt']
然后我有另一个列表
['file1', 'extrafile1', 'file2', 'file3', 'extrafile3']
所以我想做的就是得到一个匹配,该匹配生成一个像这样的字典:
{'file1': '/../../abc_file1.txt',
'extrafile1': '/../../abc_extrafile1.txt',
'file2': '/../../abc_file2.txt',
'file3': '/../../abc_file3.txt',
'extrafile3': '/../../abc_extrafile3.txt'}
所以文件名之间有一些重叠,我需要 注意这一点。
有很多方法可以执行这样的操作,但是我不确定哪种方法最有效地匹配1000或10,000个条目的列表。似乎可以通过字典理解或lambda来完成,但这似乎有点复杂。我可以编写一个原始循环,但这似乎并不是特别有效。
有关如何管理此类匹配问题的任何建议。
答案 0 :(得分:1)
您可以按照建议运行 [DataContract]
public class StringValueObject {
public string Value { get; set; }
}
StringValueObject result = JsonConvert.DeserializeObject<StringValueObject>("\"Hello world!\"");
并检查第一个列表元素的dict comprehension
(以考虑重叠)并删除扩展名:
split
输出:
list1 = ['/../../abc_file1.txt',
'/../../abc_extrafile1.txt',
'/../../abc_file2.txt',
'/../../abc_file3.txt',
'/../../abc_extrafile3.txt']
list2 = ['file1', 'extrafile1', 'file2', 'file3', 'extrafile3']
my_dict = {k: v for v in list1 for k in list2 if k == v.split('_')[1][:-4]}
答案 1 :(得分:0)
理解只是编写collection-building-loops的一种简单方法。眼睛更容易,不一定有效。
在@ matt-b答案中,dict comprehension
隐藏了一个双for
循环,对于大列表(n平方复杂度),理解变得很慢。
您的特定问题可以通过一个简单的循环来解决,并保持复杂度线性化。
使用此输入:
size = 1000
list1 = [ '/../../abc_file' + str(i) + '.txt' for i in range(size) ]
list2 = [ 'file' + str(i) for i in range(size) ]
dict comprehension
在我的计算机上花费了大约500毫秒:
my_dict = {k: v for v in list1 for k in list2 if k == v.split('_')[1][:-4]}
# 1 loop, best of 3: 516 ms per loop
以下版本的速度更快,大约1毫秒:
res = { k: None for k in list2 }
for v in list1:
name = v.split('_')[-1][:-4]
if name in res:
res[name] = v
# 100 loops, best of 3: 1.15 ms per loop
通过这种结构,可以轻松保留多个匹配项:
res = { k: [] for k in list2 }
for v in list1:
name = v.split('_')[-1][:-4]
if name in res:
res[name].append(v)
# 100 loops, best of 3: 1.54 ms per loop
您还可以通过将当前res[name]
的值与None
进行比较来保持第一个匹配项。