简体   繁体   English

确定一个元组是否是其他元组列表的子集

[英]Determining whether a tuple is a subset of a list of other tuples

I would like to determine whether a given tuple is a subset of a list of other tuples. 我想确定一个给定的元组是否是其他元组列表的子集。

I have a list of tuples, for examples: 我有一个元组列表,例如:

list_of_fails = list([[(1,2,3)],
                      [(1,2,5)],
                      [(1,4,3)]])

I would like to determine whether a given tuple is a subset of any of these tuples, for instance the tuple 我想确定给定的元组是否是这些元组中任何一个的子集,例如该元组

(1,2)

The result here would be yes,yes,no 这里的结果将是,是,否

I am able to do this when my tuples are list, for instance the following code will produce what i want: 当我的元组被列出时,我能够做到这一点,例如以下代码将产生我想要的:

list_of_fails = list([[1,2,3],
                      [1,2,5],
                      [1,4,3]]) 

for sublist in list_of_fails:

    if (set([1, 2]).issubset(sublist) == True):
        print("yes")
    else: print("no")

However converting each of my embedded tuples to a list seems rather inefficient. 但是,将每个嵌入式元组转换为列表似乎效率很低。 Is there a more efficient way to check this? 有没有更有效的方法来检查这一点?

You just need to go a level deeper. 您只需要更进一步。 Using set operations is quite efficient already. 使用设置操作已经非常有效。

%%timeit
for sublist in list_of_fails:
    for i in sublist:
        if set((1, 2)).issubset(i):
            print("yes")
        else: print("no")
#Output:
yes
yes
no
363 µs ± 91.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

With itertools.combinations: 使用itertools.combinations:

%%timeit
l = list(combinations(range(1,6), 2))
for sublist in list_of_fails:
    for i in sublist:
        for j in l:
            if set(j).issubset(i):
                print(j, i, "yes")
            else: print(j,i, "no")
#Output:
(1, 2) (1, 2, 3) yes
(1, 3) (1, 2, 3) yes
(1, 4) (1, 2, 3) no
(1, 5) (1, 2, 3) no
(2, 3) (1, 2, 3) yes
(2, 4) (1, 2, 3) no
(2, 5) (1, 2, 3) no
(3, 4) (1, 2, 3) no
..... and so on

23.8 ms ± 1.74 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

Compact and quick with list comprehensions: 紧凑而快速的列表理解功能:

%%timeit
[print(j, i,"yes") if set(j).issubset(i) else print(j, i, "no") for sublist in list_of_fails for i in sublist for j in l]
#Output:
(1, 2) (1, 2, 3) yes
(1, 3) (1, 2, 3) yes
(1, 4) (1, 2, 3) no
(1, 5) (1, 2, 3) no
(2, 3) (1, 2, 3) yes
(2, 4) (1, 2, 3) no
(2, 5) (1, 2, 3) no
...and so on
18.3 ms ± 1.94 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

As you can see, the list comprehension solution is both compact and fastest. 如您所见,列表理解解决方案既紧凑又最快。

Converting the tuple to a list is actually not that much of a performance problem. 将元组转换为列表实际上并不是性能问题。 I quickly tested this using the following code: 我使用以下代码对此进行了快速测试:

import random
import time

t0 = time.time()

rs = []
for i in range(10000):
    r1, r2 = random.randint(0, 10), random.randint(0, 10)
    t = (r1, r2)
    l = list(t)
    rs.append(l)

t1 = time.time()

print(t1 - t0)

In the second run I uncomment the l = list(t) line and change rs.append(l) to rs.append(t) . 在第二轮中,我取消对l = list(t)行的注释,并将rs.append(l)更改为rs.append(t) The results I get are: 我得到的结果是:

0.04108595848083496
0.037944793701171875

That's like 3ms per 10.000 list() calls on 2-sized tuples. 这就像在2号元组上每10.000 list()调用3ms。

I'd say your solutions is the best way to do it. 我想说您的解决方案是最好的方法。

list_of_fails = list([[(1,2,3)],
                      [(1,2,5)],
                      [(1,4,3)]])

for sublist in list_of_fails:
    if set((1, 2)).issubset(sublist[0]):
        print("yes")
    else:
        print("no")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM