#python #dictionary #tuples
#python #словарь #кортежи
Вопрос:
Если у меня есть словарь, состоящий из списка кортежей, подобных so:
d = {'ENSG00000186092': [('ENST00000641515', '3'),
('ENST00000641515', '1'),
('ENST00000641515', '2'),
('ENST00000335137', '1')],
'ENSG00000284662': [('ENST00000332831', '1')],
'ENSG00000284733': [('ENST00000426406', '1')]}
Как я могу определить, существуют ли для каждого ключа кортежи, в которых первый элемент кортежей не совпадает, но совпадают вторые элементы?
Например, в приведенном выше примере мы бы увидели только одно «попадание», и это было бы для ключа ENSG00000186092
из-за:
('ENST00000641515', '1')
('ENST00000335137', '1')
Ответ №1:
Вас заинтересует запутанное понимание списка?
[
k for k, v in d.items()
if any(
(i, j)
for i, j in v
for x, y in v
if i != x and j == y
)
]
>>> ['ENSG00000186092']
- Циклы по словарю
- Перебирает список кортежей для каждого ключа
- Для каждого кортежа выполните цикл по одному и тому же списку и проверьте, не совпадают ли первые записи, но совпадают вторые
- Если таковые найдутся, запишите этот ключ с шага 2.
Комментарии:
1. Мне это кажется прекрасным! Если я хочу, чтобы на выходе были соответствующие кортежи вместо ключа, как мне это сделать?
2. Измените элемент, который хранится в результирующем списке; эта строка
k for k, v in d.items()
становитсяv for k, v in d.items()
(или действительноv for _, v in d.items()
, потому чтоk
не используется).3. О, подождите, это возвращает все кортежи для совпадающих ключей.
4. Вы можете просмотреть список и использовать ключи для извлечения списков кортежей, а затем выполнить с ними ту же логику, что и внутри
any()
функции:[(i, j) for k in [k for k, v in d.items() if any((i, j) for i, j in v for x, y in v if i != x and j == y)] for i, j in d[k] for x, y in d[k] if i != x and j == y]
. Теперь это действительно начинает обретать форму! Ужасная форма.5. Хорошо, я попробовал это и заметил, что в результате получаю дубликаты, поэтому я попытался настроить результат, но продолжаю получать ошибки типа
unhashable type 'list'
Ответ №2:
d = {'ENSG00000186092': [('ENST00000641515', '3'),
('ENST00000641515', '1'),
('ENST00000641515', '2'),
('ENST00000335137', '1')],
'ENSG00000284662': [('ENST00000332831', '1')],
'ENSG00000284733': [('ENST00000426406', '1')]}
for k, a in d.items():
a_s = sorted(a, key=lambda x: (x[1], x[0]))
for i in range(len(a_s)-1):
if a_s[i][1] == a_s[i 1][1] and a_s[i][0] != a_s[i 1][0]:
print (k, a_s[i], a_s[i 1])
- Сортируйте кортежи по второму элементу, затем по первому элементу кортежей, чтобы кортежи объединялись по второму элементу, а затем по первому элементу
- Проверьте условие между текущим кортежем и следующим кортежем в отсортированном списке и распечатайте их, если условие выполнено
- Временная сложность если
d
имеетk
элементы и размер списка равен ‘n’, то этоO(k*nlogn)
[k
для внешнего цикла иnlogn
для сортировки]
Ответ №3:
Быть очень подробным:
d = {
"ENSG00000186092": [
("ENST00000641515", "3"),
("ENST00000641515", "1"),
("ENST00000641515", "2"),
("ENST00000335137", "1"),
],
"ENSG00000284662": [("ENST00000332831", "1")],
"ENSG00000284733": [("ENST00000426406", "1")],
}
def has_duplicates(list_of_tuples):
seen = set()
for _, value in list_of_tuples:
if value in seen:
return True
seen.add(value)
return False
dupes = [key for key, value in d.items() if has_duplicates(value)]
print(dupes)
has_duplicates
Функция принимает значение из вашего словаря. Возвращает True, если какой-либо из кортежей в этом значении имеет то же второе значение.
Понимание списка при возврате дает вам, что все ключи были has_duplicates
истинными.