包含特定元组的元组索引列表

2024-10-01 00:30:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含3个子元组列表的列表,如

[[(['A', 'B', 'A'], ['B', 'O', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'O']),
  (['A', 'B', 'O'], ['B', 'O', 'A']),
  (['A', 'B', 'O'], ['B', 'A', 'O']),
  (['A', 'B', 'A'], ['B', 'O', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'O'])],
 [(['A', 'B', 'A'], ['B', 'A', 'A']),
  (['A', 'B', 'O'], ['B', 'A', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'A'])],
 [['A', 'B', 'A'], ['A', 'B', 'O']],
 [['A', 'B', 'B']],
 [['B', 'A', 'A']]]

假设list2 = ['A', 'B', 'A'].我的目标是获得list1中包含元组list2的任何元组对(或元组的单态集)的索引列表。我尝试按如下方式使用enumerate函数,但结果不正确

print([i for i, j in enumerate(bigset) if ['A', 'B', 'A'] in j[0] or 
       ['A', 'B', 'A'] == j[0] or [['A', 'B', 'A']] in j[0]])

有人能帮我解决这个问题吗?由于list1中出现的元组的不同大小的不匹配,我非常困惑

我的另一个问题是:我想在list1中找到三元素列表的总数。因此,如果我用手来做,答案是22。但是如何在代码中实现呢?我想我们需要使用两个for循环

预期输出对于上面的list1和给定的list2,我们将得到包含list2的索引列表是[0,1,5,6,7,9,10]


Tags: or函数in目标列表for方式元组
3条回答

好的,给你

这将使用递归,因为我们不知道list1的深度,所以索引将按如下方式计算:

0,1
2,3,4,
6,7
8,
9,10,11,12

等等。。。(与您在一行中书写的顺序相同)

结果如下:

[0, 2, 8, 10, 12, 16, 18]

现在是代码

def foo(l,ref):
    global s
    global indexes
    for items in l:  #if it's an element of 3 letters
        if len(items)== 3 and len(items[0])==1:
            if items == ref: 
                indexes.append(s) #save his index if it match the ref
            s+= 1  #next index
        else: #We need to go deeper
            foo(items,ref)
    return(s)
          
        
list1 = [[(['A', 'B', 'A'], ['B', 'O', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'O']),
  (['A', 'B', 'O'], ['B', 'O', 'A']),
  (['A', 'B', 'O'], ['B', 'A', 'O']),
  (['A', 'B', 'A'], ['B', 'O', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'O'])],
 [(['A', 'B', 'A'], ['B', 'A', 'A']),
  (['A', 'B', 'O'], ['B', 'A', 'A']),
  (['A', 'B', 'A'], ['B', 'A', 'A'])],
 [['A', 'B', 'A'], ['A', 'B', 'O']],
 [['A', 'B', 'B']],
 [['B', 'A', 'A']]]

list2 = ['A', 'B', 'A']
indexes = []
s=0
count= foo(list1,list2)
print(indexes)

s是我们正在研究的索引 count是元素(22)的总量。 Indexes是您想要的索引列表

这项工作即使你做了一个list3 = [list1,list1,[list1,[list1],list1]],你也可能想试试

祝你好运,现在结束你的脚本

如果我们先将列表1整理成更友好的格式,对您的实现有用吗?如果是这样的话,你可以用一种非常简单的方式:

检查list1的每个元素,如果元素本身是一个元组的大列表,那么我们希望进一步解包。如果该元素是一个元组(因此该元组的第一个元素是一个列表),或者它本身就是一个3元素列表,那么我们只想按原样附加它

nice_list = []
for i in list1:
    if type(i[0]) == str or type(i[0]) == list:
        # i.e. i is one of your 3-element lists, or a tuple of lists
        nice_list.append(i)
    else:
        #If i is still a big list of other tuples, we want to unpack further
        for j in i:
            nice_list.append(j)

然后,您可以更轻松地搜索索引:

for i, idx in zip(nice_list, range(len(nice_list))): 
    if ['A', 'B', 'A'] in i: 
        print(idx) #Or append them to a list, whatever you wanted to do

对于您关于查找有多少个3元素列表的问题,如果不是特别优雅的解决方案,可以使用For循环:

no_of_lists = 0
for n in nice_list:
    if type(n) == tuple:
        no_of_lists += len(n)
    elif type(n) == list and type(n[0]) == list:
        # if it is a list of lists
        no_of_lists += len(n)
    elif type(n) == list and type(n[0]) == str:
        #if it is a 3-element list
        no_of_lists_lists += 1
print('Number of 3-element lists contained:', no_of_lists)

编辑:为了回答您在评论中提出的关于for n in nice_list部分如何工作的问题,只需迭代列表中的每个元素。要探索这一点,请尝试编写一些代码来打印nice_list[0]nice_list[1]等,或者编写一个for循环来打印每个n,这样您就可以看到它是什么样子了。例如,您可以执行以下操作:

for n in nice_list:
    print(n)

去了解它是如何工作的

由于深度未知和/或缺少已知的阵列展平操作,这种方法有点非常规-我会尝试使用正则表达式:

import re

def getPos(el, arr):
    el=re.escape(str(el))
    el=f"(\({el})|({el}\))"
    i=0
    for s in re.finditer(r"\([^\)]+\)", str(arr)):
        if(re.match(el,s.group(0))):
            yield i
        i+=1

这将产生:

>>> print(list(getPos(list2, list1)))

[0, 1, 4, 5, 6, 8, 9]

(我相信这就是你想要的实际结果)

相关问题 更多 >