dict があり、空の値の文字列があるすべてのキーを削除したいと考えています。
metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
u'EXIF:CFAPattern2': u''}
これを行う最善の方法は何ですか?
dict があり、空の値の文字列があるすべてのキーを削除したいと考えています。
metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
u'EXIF:CFAPattern2': u''}
これを行う最善の方法は何ですか?
Python 2.X
dict((k, v) for k, v in metadata.iteritems() if v)
Python 2.7 - 3.X
{k: v for k, v in metadata.items() if v}
すべてのキーに値があることに注意してください。これらの値の一部が空の文字列であることだけです。値のない dict にはキーのようなものはありません。値がない場合は、dict に含まれません。
元の辞書を本当に変更する必要がある場合:
empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
del metadata[k]
空のキーのリストを作成する必要があることに注意してください。これは、反復処理中に辞書を変更できないためです (お気づきかもしれません)。ただし、空の値を持つエントリが多数ない限り、これは真新しいディクショナリを作成するよりもコストがかかりません (メモリの観点から)。
多くの場合ネストされ、サイクルを含むことさえある実世界のデータ構造を処理するためのフル機能でありながら簡潔なアプローチが必要な場合は、boltons ユーティリティ パッケージの remap ユーティリティを参照することをお勧めします。
プロジェクトにiterutils.pypip install boltons
をコピーまたはコピーした後、次のようにします。
from boltons.iterutils import remap
drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)
このページには、Github の API からのはるかに大きなオブジェクトを操作するものなど、さらに多くの例があります。
これは純粋な Python であるため、どこでも機能し、Python 2.7 および 3.3+ で完全にテストされています。何よりも、私はまさにこのようなケースのために書いたので、処理できないケースを見つけた場合は、ここでバグを修正することができます.
Ryan's solutionに基づいて、リストとネストされた辞書もある場合:
Python 2 の場合:
def remove_empty_from_dict(d):
if type(d) is dict:
return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
elif type(d) is list:
return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
else:
return d
Python 3 の場合:
def remove_empty_from_dict(d):
if type(d) is dict:
return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
elif type(d) is list:
return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
else:
return d
BrenBarn のソリューションは理想的です (そして pythonic だと付け加えるかもしれません)。ただし、別の(fp)ソリューションを次に示します。
from operator import itemgetter
dict(filter(itemgetter(1), metadata.items()))
ネストされた辞書があり、空のサブ要素に対してもこれを機能させたい場合は、BrenBarn の提案の再帰的バリアントを使用できます。
def scrub_dict(d):
if type(d) is dict:
return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
else:
return d
### example01 -------------------
mydict = { "alpha":0,
"bravo":"0",
"charlie":"three",
"delta":[],
"echo":False,
"foxy":"False",
"golf":"",
"hotel":" ",
}
newdict = dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(vdata) ])
print newdict
### result01 -------------------
result01 ='''
{'foxy': 'False', 'charlie': 'three', 'bravo': '0'}
'''
### example02 -------------------
mydict = { "alpha":0,
"bravo":"0",
"charlie":"three",
"delta":[],
"echo":False,
"foxy":"False",
"golf":"",
"hotel":" ",
}
newdict = dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(str(vdata).strip()) ])
print newdict
### result02 -------------------
result02 ='''
{'alpha': 0,
'bravo': '0',
'charlie': 'three',
'delta': [],
'echo': False,
'foxy': 'False'
}
'''
patriciaszとnneonneoからの回答に基づいて構築し、特定の偽物のみを含むキー (例: ''
) を削除し、他のものを含まないキー (例: 0
)、またはいくつかの真実のものを含めたい場合(例: 'SPAM'
)の可能性を説明します。、次に非常に具体的なヒットリストを作成できます。
unwanted = ['', u'', None, False, [], 'SPAM']
残念ながら、これはうまくいきませ0 in unwanted
んTrue
。0
と他の偽物を区別する必要があるため、以下を使用する必要がありますis
。
any([0 is i for i in unwanted])
... に評価されFalse
ます。
del
不要なものに使用します。
unwanted_keys = [k for k, v in metadata.items() if any([v is i for i in unwanted])]
for k in unwanted_keys: del metadata[k]
その場で変更するのではなく、新しい辞書が必要な場合metadata
:
newdict = {k: v for k, v in metadata.items() if not any([v is i for i in unwanted])}
if isinstance(v, list):
scrub_dict(d)
@staticmethod
def scrub_dict(d):
new_dict = {}
for k, v in d.items():
if isinstance(v, dict):
v = scrub_dict(v)
if isinstance(v, list):
v = scrub_list(v)
if not v in (u'', None, {}, []):
new_dict[k] = v
return new_dict
@staticmethod
def scrub_list(d):
scrubbed_list = []
for i in d:
if isinstance(i, dict):
i = scrub_dict(i)
scrubbed_list.append(i)
return scrubbed_list
"As I also currently write a desktop application for my work with Python, I found in data-entry application when there is lots of entry and which some are not mandatory thus user can left it blank, for validation purpose, it is easy to grab all entries and then discard empty key or value of a dictionary. So my code above a show how we can easy take them out, using dictionary comprehension and keep dictionary value element which is not blank. I use Python 3.8.3
data = {'':'', '20':'', '50':'', '100':'1.1', '200':'1.2'}
dic = {key:value for key,value in data.items() if value != ''}
print(dic)
{'100': '1.1', '200': '1.2'}
metadata ={'src':'1921','dest':'1337','email':'','movile':''}
ot = {k: v for k, v in metadata.items() if v != ''}
print(f"Final {ot}")