У меня есть словарь Python, ключ словаря состоит из кортежей,

Как это :

{
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
}

Я хотел бы удалить все ключи из словаря, когда в ключе появляется только часть кортежа:

Например 'Remove_'

В этом случае должны появиться два ключа: один содержит u'Remove_Me', а другой содержит u'Remove_Key'

Наконец, словарь будет выглядеть так:

{
  (u'A_String_0', u'B_String_4'): 301
}

Большое спасибо !

3
Toren 22 Дек 2015 в 15:25

4 ответа

Лучший ответ

В одну сторону:

    >>> d = {
     (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
     (u'A_String_0', u'B_String_4'): 301, 
     (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
    }
    >>> 
    >>> 
    >>> d_out = {k:v for k,v in d.items() if not any(x.startswith('Remove_') for x in k)}
    >>> d_out
{(u'A_String_0', u'B_String_4'): 301}

РЕДАКТИРОВАТЬ: Если вы хотите проверить, является ли Remove_ частью какого-либо элемента ключа кортежа, то вам лучше с:

>>> d_out = {k:v for k,v in d.items() if not any('Remove_' in x for x in k)}
7
Iron Fist 22 Дек 2015 в 12:38

Поскольку ключи всегда объединены без какой-либо структуры или шаблона, вам всегда нужно иметь полный ключ для доступа к элементам в словаре. В частности это означает, что вы не можете найти элементы, используя какой-то частичный ключ. Таким образом, для этого нет другого способа, кроме как просмотреть все ключи:

>>> d = {
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301}
>>> { k: v for k, v in d.items() if not any(x.startswith('Remove_') for x in k) }
{(u'A_String_0', u'B_String_4'): 301}

Это создаст новый словарь из исходного словаря, взяв каждый ключ k, для которого any(x.startswith('Remove_') for x in k) не соответствует действительности. Это any() выражение будет истинным, если в x есть элемент, который начинается с 'Remove_'.

5
poke 22 Дек 2015 в 12:30

Если это sartswith, вы уже получили свой ответ. Если нет, то вы можете использовать in или re for more complex checking

Код:

import re
dic = {
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
 (u'A_String_0', u'B_String_4'): 301, 
 (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
}
print {k:v for k,v in dic.items() if not any(re.match("Remove", val)for val in k)} # Using in
print {k:v for k,v in dic.items() if not any("Remove" in val for val in k)} # Using re.match

Вывод:

{(u'A_String_0', u'B_String_4'): 301}

Примечание.

  • Это удалит ключ, если Remove произойдет в любом месте ключа
2
The6thSense 22 Дек 2015 в 12:38

Использование одного и того же словаря, а не однострочного. Также обратите внимание, что в оригинальном сообщении говорилось, что «часть кортежа появляется в ключе», поэтому не должно быть в начале, т.е. startswith()

>>> d = {
...      (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Me'): 300, 
...      (u'A_String_0', u'B_String_4'): 301, 
...      (u'A_String_0', u'A_String_1', u'B_String_3', u'Remove_Key'): 301,
...     }
>>> for k in d.keys():
...     for i in k:
...         if 'Remove_' in i:
...             del d[k]
...             break
... 
>>> d
{(u'A_String_0', u'B_String_4'): 301}
2
Saksow 22 Дек 2015 в 12:35