Python-在列表列表中查找元组

Python-在列表列表中查找元组,python,Python,我有元组列表mytuples和列表mylist 我想找出mytuples中的每个元组在每个列表中出现的次数 假设元组2,3出现在[1,2,3,4]、[2,3,4,5]和[2,3]中。因此,2,3的计数是3 元组和列表大小可以不同 mytuples = [(2,3), (3,6), (1,2)] mylist = [[1,2,3,4],[2,3,4,5],[2,3],[4,5,6]] count={} for m in mytuples : counter = 0

我有元组列表mytuples和列表mylist

我想找出mytuples中的每个元组在每个列表中出现的次数

假设元组2,3出现在[1,2,3,4]、[2,3,4,5]和[2,3]中。因此,2,3的计数是3

元组和列表大小可以不同

mytuples = [(2,3), (3,6), (1,2)]
mylist = [[1,2,3,4],[2,3,4,5],[2,3],[4,5,6]]

count={}    
for m in mytuples :
    counter = 0        
    for i in mylist :
        if set(m).issubset(i):
            counter = counter + 1
    count[m]=counter
我的输出是{2,3:3,3,6:0,1,2:1}

这种方法可以很好地工作,但是当我的列表大小很大(比如1000条记录)时,它会更加耗时。这能做得更快吗?有什么建议吗?

使用听写理解,我们可以将所有内容简化为一行

假设元组总是成对的:

count = {(x,y):sum((x in i and y in i) for i in mylist) for x,y in mytuples}
# {(1, 2): 1, (2, 3): 3, (3, 6): 0}
或者,如果元组大小未知,则可以使用all求和:

count = {t:sum(all(x in i for x in t) for i in mylist) for t in mytuples}
# {(1, 2): 1, (2, 3): 3, (3, 6): 0}
如果不清楚:

我们经历了多个过程:

[all(x in i for x in (2,3)) for i in mylist]
# [True, True, True, False] 
# sum([True, True, True, False]) = 3
# And we assign them back to the tuple
通过听写理解,我们可以将所有内容简化为一行

假设元组总是成对的:

count = {(x,y):sum((x in i and y in i) for i in mylist) for x,y in mytuples}
# {(1, 2): 1, (2, 3): 3, (3, 6): 0}
或者,如果元组大小未知,则可以使用all求和:

count = {t:sum(all(x in i for x in t) for i in mylist) for t in mytuples}
# {(1, 2): 1, (2, 3): 3, (3, 6): 0}
如果不清楚:

我们经历了多个过程:

[all(x in i for x in (2,3)) for i in mylist]
# [True, True, True, False] 
# sum([True, True, True, False]) = 3
# And we assign them back to the tuple

只需稍作调整,您当前的算法就会变得更快:

# Your input data.
tuples = [(2,3), (3,6), (1,2)]
lists = [[1,2,3,4],[2,3,4,5],[2,3],[4,5,6]]

# Convert to sets just once, rather than repeatedly
# within the nested for-loops.
subsets = {t : set(t) for t in tuples}
mainsets = [set(xs) for xs in lists]

# Same as your algorithm, but written differently.
tallies = {
    tup : sum(s.issubset(m) for m in mainsets)
    for tup, s in subsets.items()
}

print(tallies)

只需稍作调整,您当前的算法就会变得更快:

# Your input data.
tuples = [(2,3), (3,6), (1,2)]
lists = [[1,2,3,4],[2,3,4,5],[2,3],[4,5,6]]

# Convert to sets just once, rather than repeatedly
# within the nested for-loops.
subsets = {t : set(t) for t in tuples}
mainsets = [set(xs) for xs in lists]

# Same as your algorithm, but written differently.
tallies = {
    tup : sum(s.issubset(m) for m in mainsets)
    for tup, s in subsets.items()
}

print(tallies)


元组/列表中项目的顺序重要吗?您可以更改数据结构,还是只更改算法?通常这两者应该齐头并进。列表总是按顺序排列的。元组可以是任意顺序。顺序也不重要。@PeterWood我不能改变数据结构。只有算法。但是如果可以通过改变数据结构来提高速度,那么我可以试试。但这是最后一个选项。元组/列表中项目的顺序重要吗?您可以更改数据结构,还是只更改算法?通常这两者应该齐头并进。列表总是按顺序排列的。元组可以是任意顺序。顺序也不重要。@PeterWood我不能改变数据结构。只有算法。但是如果可以通过改变数据结构来提高速度,那么我可以试试。但这是最后一个选择。这比Anton vBR建议的速度还要快。您的解决方案在一个大列表上运行良好。我尝试了大小为541909和元组大小为3363671的列表。。但它运行了30分钟。“它能更优化吗?”学习者没有什么明显的东西向我扑来。如果您正在处理如此规模的数据量,而不是试图从该算法中挤出更多的优化,您可能希望退后一步,看看是否可以使用不同的算法解决您的根本问题。这比Anton vBR建议的更快。您的解决方案在大列表中效果良好。我尝试了大小为541909和元组大小为3363671的列表。。但它运行了30分钟。“它能更优化吗?”学习者没有什么明显的东西向我扑来。如果您正在处理如此规模的数据量,而不是试图从该算法中挤出更多的优化,您可能希望退后一步,看看您的根本问题是否可以用其他算法解决。该解决方案还显著缩短了时间。@Learner Yeap,使用集合是很快的。我认为我的第一个解决方案是在一个小集合上尝试时速度最快的,但是我也投票支持FMc的解决方案。Fast很好,但是当我使用python时,我更喜欢可读性而不是Fast。这个解决方案还显著减少了时间。@是的,使用集合很快。我认为我的第一个解决方案是在一个小集合上尝试时速度最快的,但是我也投票支持FMc的解决方案。Fast很好,但是当我使用python时,我更喜欢可读性而不是Fast。