#python #python-3.x #tuples
#python #python-3.x #кортежи
Вопрос:
У меня есть список list1
из 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
.
Еще один вопрос, который у меня есть: я хочу найти общее количество списков из 3 элементов в list1
. Итак, если я сделаю это вручную, ответ будет 22
. Но как это сделать в коде? Я думаю, нам нужно использовать два for
цикла?
Ожидаемый результат Для list1
приведенного выше list2
мы получили бы список индексов, содержащих list2
is [0,1,5,6,7,9,10]
.
Комментарии:
1. У вас есть список из пяти списков, внутренние списки, иногда содержащие кортежи, содержащие списки. Пожалуйста, поделитесь точным результатом, который вы хотите получить
list1
.2. В опубликованном коде нет «кортежей кортежей». В основном у вас есть списки с несколькими кортежами здесь и там. Это почти невозможно прочитать как опубликовано. Почему бы не разделить длинную строку?
3. Это очень неорганизованно. Вам лучше изменить его на более удобный формат (например, список списков кортежей) и пересмотреть, чего вы хотите достичь
4. @timgeb: Я показал точный результат, который мне нужен
list1.
Можете ли вы, пожалуйста, помочь? Причина, по которой у меня естьtuples
, заключается в том, что я использую функциюlist(itertools.product())
для создания этих пар.5. @TomKarzes: пожалуйста, рассматривайте каждую пару кортежей как элемент в большом списке. Меня интересует только получение списка позиций тех пар, которые содержат данный кортеж в
list2.
Теперь вам это понятнее?
Ответ №1:
Хорошо, итак, поехали
Это использует рекурсию, потому что мы не знаем глубину вашего list1
ПОЭТОМУ индекс будет подсчитываться следующим образом :
0,1
2,3,4,
6,7
8,
9,10,11,12
и т.д… (Тот же порядок, который вы имеете, записав его в 1 строку)
Здесь результатом будет :
[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]]
, вы можете попробовать это.
Желаю удачи в завершении вашего сценария сейчас.
Ответ №2:
Будет ли это работать для вашей реализации, если мы сначала отсортируем ваш list1 в более удобный формат? Если это так, вы могли бы сделать это довольно простым способом:
Пройдите по каждому элементу 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)
чтобы понять, как это работает.
Комментарии:
1. не могли бы вы уточнить
If
условие? Чтоstr
иlist
в данном случае означают?2. большое вам спасибо за вашу помощь. Это потрясающе! Я попробовал ваш код, чтобы определить, сколько существует списков из 3 элементов, и, по-видимому, результат равен 21. а не 22. Я думаю, что это может не учитывать элемент типа либо
[['A', 'B', 'A'], ['A', 'B', 'O']]
, либо[['A', 'B', 'B']]
3. Ах, извините за это, когда я сделал это в первый раз, он вернул 22, как и ожидалось! Позвольте мне просто зайти и исправить это
4. однако добавлен еще один вопрос. Если я хочу определить переменную b [i] так, чтобы b [1] = 2, если первые элементы кортежа первого подсписка равны 2 (и b [1] = 1 в противном случае), b [2] = 2, если вторые элементы кортежа первого подсписка равны 2, и так далее, тогда у меня был бы ожидаемый результат от
list1
as[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1].
Можете ли вы помочь мне достичь этой цели?5. Это довольно просто, только
b = [len(i) for i in nice_list]
для вашего первого вопроса, а затемlen(b)
для вашего второго. Также, пожалуйста, не забудьте проголосовать / отметить ответы как правильные, если они помогут вам, это действительно помогает тем из нас, кто является относительно новым!
Ответ №3:
Немного нетрадиционный подход из-за неизвестной глубины и / или отсутствия известной операции выравнивания массива — я бы попробовал с регулярным выражением:
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]
(Я считаю, что это фактический результат, который вы хотите).
Комментарии:
1. Большое вам спасибо за вашу помощь. Вы использовали Python 3? Я попробовал ваш код, но я получил ошибку
el=f"(({el})|({el}))" ^ SyntaxError: invalid syntax
2. Да, python3 — для более ранних версий просто сделайте :
el="(({0})|({0}))".format(el)