python中带有元组列表的字符串列表的条件笛卡尔积的单线

Posted

技术标签:

【中文标题】python中带有元组列表的字符串列表的条件笛卡尔积的单线【英文标题】:One-liner for conditional Cartesian Product of list of strings with list of tuples in python 【发布时间】:2018-03-26 03:16:52 【问题描述】:

我有一个字符串列表和一个元组列表。

输入:

string_list = ['www.cars.com/BMW/' ,'www.cars.com/VW/']
tuple_list = [('BMW','green'), ('BMW','blue'), 
               ('VW','black'), ('VW','red'), ('VW','yellow')]

第一步:对于string_list 中的每个键,我需要过滤tuple_list 中匹配的键/值对:

string_list = ['www.cars.com/BMW/']
tuple_list = [('BMW','green'), ('BMW','blue')]

第二步:在一个最终输出列表中,我需要将string_list 中的所有字符串与tuple_list 中的每个匹配键/值对形成笛卡尔积:

输出:

results_list = ['www.cars.com/BMW/green','www.cars.com/BMW/blue', 
  'www.cars.com/VW/black''www.cars.com/VW/red','www.cars.com/VW/yellow']

我目前的方法使用了一系列嵌套的for-loops,其代价是缓慢、丑陋和太长。

python中如何高效地在字符串列表和元组列表之间形成条件笛卡尔积?

【问题讨论】:

是VM还是VW? 大众,已编辑(抱歉) 你真的需要这个作为一个列表,还是任何你可以迭代的东西?因为如果您不需要列表,itertools.product 或嵌套的genexpr 可能会比嵌套的listcomp 更快,但是listcomp 可能比将其中任何一个传递给list 构造函数更快。 任何可迭代的都可以,列表并不是真正需要的 【参考方案1】:

一个班轮:

result = [s + b for s in string_list for a, b in tuple_list if a in s]

基本上还是两个for循环。

>>> print(result)
['www.cars.com/BMW/green', 'www.cars.com/BMW/blue', 'www.cars.com/VW/black', 'www.cars.com/VW/red', 'www.cars.com/VW/yellow']

【讨论】:

像魅力一样工作,速度快 10 倍,而且只有 1 个 SLOC - 完美【参考方案2】:

你可以试试:

string_list = ['www.cars.com/BMW/' ,'www.cars.com/VW/']
tuple_list = [('BMW','green'), ('BMW','blue'),
               ('VW','black'), ('VW','red'), ('VW','yellow')]


print([color+i[1] for i in tuple_list for color in string_list if i[0] in color])

输出:

['www.cars.com/BMW/green', 'www.cars.com/BMW/blue', 'www.cars.com/VW/black', 'www.cars.com/VW/red', 'www.cars.com/VW/yellow']

【讨论】:

【参考方案3】:

如果您为查找预先构建字典,则可以进一步提高性能:

给定

import collections as ct


colors =  ct.defaultdict(list)
for k, v in tuple_list:
    colors[k].append(v)

colors
# defaultdict(list, 'BMW': ['green', 'blue'], 'VW': ['black', 'red', 'yellow'])

代码

[s + c for s in string_list for c in colors[s[13:-1]]]

输出

['www.cars.com/BMW/green',
 'www.cars.com/BMW/blue',
 'www.cars.com/VW/black',
 'www.cars.com/VW/red',
 'www.cars.com/VW/yellow']

性能

%timeit -n 100000 [s + b for s in string_list for a, b in tuple_list if a in s]  # @iBug
%timeit -n 100000 [s + c for s in string_list for c in colors[s[13:-1]]]         # proposed    
# 100000 loops, best of 3: 3.54 µs per loop
# 100000 loops, best of 3: 2.83 µs per loop

【讨论】:

以上是关于python中带有元组列表的字符串列表的条件笛卡尔积的单线的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记#元组和列表的区别

简述啥是关系、元组、属性、域、主码?

第6天数据类型之元组,字典,集合

python开发基础:元祖操作

牛客编程题python入门103题(输入&类型,字符串&列表&字典&元组,运算&条件&循环,函数&类&正则)

数据库笛卡尔积