簡體   English   中英

刪除值為空列表的字典的鍵

[英]Delete keys of a dictionary whose values are empty lists

我有一本字典,其中一些與鍵相對應的值是空列表。 我想刪除所有這些鍵

d = {'Receipt total': [], 'Total Amount (AED)': [], 'Grand total': [], 'Net Amount': [], 'Total': ['105.00'], 'Total (AED)': [], 'Total Invoice Amount': [], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

預期 output:

d = {'Total': ['105.00'], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

我試過了:

for key, value in d.items():
    if value is None:
        del d[k]

我的代碼不起作用

您可以改用字典理解

d = {'Receipt total': [], 'Total Amount (AED)': [], 'Grand total': [], 'Net Amount': [], 'Total': ['105.00'], 'Total (AED)': [], 'Total Invoice Amount': [], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}
    
d = {k: v for k, v in d.items() if v != []}

print(d)

# d = {'Total': ['105.00'], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

您可能需要明確檢查該值是否為[] 否則,您可能會刪除碰巧評估為False (“falsey”)的內容,例如您可能不想要的 0 值。 當然,只有當您的 dict 可以包含列表以外的內容作為值時,這一點才有意義。

您可以像這樣使用字典理解:

d = {'Receipt total': [], 'Total Amount (AED)': [], 'Grand total': [], 'Net Amount': [], 'Total': ['105.00'], 'Total (AED)': [], 'Total Invoice Amount': [], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

#use dictionary comprehensiion to create a new list of values where they value is not an empty list
d = {key : value for key, value in d.items() if len(value) != 0}

print(d)

Output: {'Total': ['105.00'], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

通過使用 for 循環刪除字典的項目,它會引發RuntimeError: dictionary changed size during iteration

你的想法至少有三個錯誤。

第一個是空列表與None相同。

只有NoneNone相同。

其次,比較列表,你應該使用== 使用is來比較一個列表意味着,即使一個列表中的值相同,如果它不是實際相同的 memory 地址,它也不會比較相等。

此外,由於您只想知道列表是否為空,您可以使用以下事實:在 Python 中,空序列被視為False並且非空被視為True ,因此您可以使用 boolean 條件: if not value:這將為空列表為True 如果值可以是列表以外的東西,那么空字符串、零等也都是False ,因此您可能需要更仔細地檢查。

第三,您不應該在迭代容器時像dict一樣修改容器的大小。 要么迭代它的副本,要么創建要修改的內容的記錄,然后執行修改。

第一種方式,遍歷副本:

for key, value in list(d.items()):
    if not value:
        del d[key]

第二種方法,制作一組要刪除的鍵:

keys_to_remove = {key for key, value in d.items()
                  if not value}

for key in keys_to_remove:
    del d[key]

如果這些值都是列表,那么您可以使用它們的真實性,您可以使用itertools.compress

>>> dict(compress(d.items(), d.values()))
{'Total': ['105.00'], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

您可以使用:

d = {'Receipt total': [], 'Total Amount (AED)': [], 'Grand total': [], 'Net Amount': [], 'Total': ['105.00'], 'Total (AED)': [], 'Total Invoice Amount': [], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

res = {}

for key, value in d.items():
    if value:
        res[key] = value

res
# {'Total': ['105.00'], 'Invoice total': ['105.00'], 'Amount Due': ['0.00']}

不建議在 for 循環期間從容器中刪除項目,最好創建一個新項目並添加您需要的項目,而不是從原始項目中刪除您不需要的項目。

例如:

a = [1,2,2,3]
for item in a:
    if item > 1:
        a.remove(item)
a
# [1, 2]

留下第二個2因為一旦你刪除了第一個2你移動了索引並且你的 for 循環已經檢查了索引1但是現在你的第二個2在索引1並且它沒有被選中。

嘗試這個:

result = {k:v for k,v in d.items() if v}

關於什么:

new_d = dict((k,v) for k,v in d.items() if v)

如果你想覆蓋d只需將new_d更改為d

有一些風險可能會給出錯誤的結果:

if v when v = []將評估為 Falsly,與0相同,因此它可能會刪除錯誤的鍵。 在我的回答中,我沒有解決這個問題。 可以參考以下鏈接更好地理解: 什么是真假? 它與真假有什么不同?

您擁有的字典d的類型是Dict[str, List[str]] 它的初始化方式意味着所有鍵的值都不是None ,而是空列表。 例如:

>>> listOfNothing = []

>>> print(listOfNothing)
[]

>>> print(type(listOfNothing))
<class 'list'>

如果您想檢查列表是否為空(值是否為空列表),我建議您這樣做:

for key, value in d.items():
    if len(value) == 0:
        [do something]

但是,正如其他人正確指出的那樣,您無法在迭代字典時更改字典的大小。 這可以通過創建一個新字典來解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM