如何从字典值中删除列表项?

4

我有一个主机字典,其中包含一个主机名键和列表值。我希望能够从每个值的列表中删除任何水果_项。

host = { 
  'abc.com': ['fruit_apple', 'fruit_orange', 'veg_carrots'], 
  '123.com': None, 
  'foo.com': ['fruit_tomatoes', 'veg_potatoes']
}

for v in host.values():
  if v is not None:
    for x in v:
      try:
        # creating my filter
        if x.startswith('fruit_'):
        # if x finds my search, get, or remove from list value
         host(or host.value()?).get/remove(x)# this is where i'm stuck
        print(hr.values(#call position here?)) # prove it
      except:
        pass

我卡在了被注释的区域,感觉我可能缺少另一个迭代(新的列表?),或者我不理解如何将列表值写回。任何方向都将有所帮助。


在你的例子中,if v is not None: 总是会是 True。你可能已经知道了。 - James Schinner
没问题。我猜你在host的值中有一个None没有发布?我只是想确保你不认为它会捕获[None] - James Schinner
我想我应该更新一下,'123.com': [ None ],应该改为 '123.com': None,而不是在列表中。 - hobbes
没问题,我并不是要挑剔,我猜你已经知道了! - James Schinner
3个回答

6
使用带有过滤条件的列表推导式并创建一个新列表是更好的从列表中筛选项目的方法,像这样。
host = {
    'abc.com': ['fruit_apple', 'fruit_orange', 'veg_carrots'],
    '123.com': [None],
    '456.com': None,
    'foo.com': ['fruit_tomatoes', 'veg_potatoes']
}


def reconstruct_list(vs):
    return vs if vs is None else [
        v for v in vs if v is None or not v.startswith('fruit_')
    ]


print({k: reconstruct_list(vs) for k, vs in host.items()})

输出

{'abc.com': ['veg_carrots'], '123.com': [None], '456.com': None, 'foo.com': ['veg_potatoes']}

在这种情况下,列表的单个值被过滤,并使用字典推导式创建了一个新的字典对象。

@hobbes 我认为你的数据在某些情况下具有None作为值,而不是[None]。这正确吗? - thefourtheye
没错,我已经在上面进行了更新。它不应该出现在列表中。 - hobbes
1
@hobbes 我更新了答案以适应两个“None”情况。它只是从过滤中忽略了“None”。 - thefourtheye
哇,那就做到了,谢谢!我需要一些时间来消化列表推导式,我有点理解了,但仍然在努力将其分解成块,并按操作顺序排序。 - hobbes
1
@hobbes 从这里开始。 - thefourtheye

1

用字典推导式重建字典怎么样:

>>> host = { 
  'abc.com': ['fruit_apple', 'fruit_orange', 'veg_carrots'], 
  '123.com': [None] , 
  'foo.com': ['fruit_tomatoes', 'veg_potatoes']
}

>>> {k: [x for x in v if not str(x).startswith('fruit_') or not x] for k, v in host.items()}
{'abc.com': ['veg_carrots'], '123.com': [None], 'foo.com': ['veg_potatoes']}

如果'123.com'的值为None,您可以这样做:
>>> host = { 
  'abc.com': ['fruit_apple', 'fruit_orange', 'veg_carrots'], 
  '123.com': None , 
  'foo.com': ['fruit_tomatoes', 'veg_potatoes']
}

>>> {k: v if not v else [x for x in v if not x.startswith('fruit_')] for k, v in host.items()}
{'abc.com': ['veg_carrots'], '123.com': None, 'foo.com': ['veg_potatoes']}

这个对比起你分解的示例和上面发布的那一个来看,是一个很好的参考。谢谢你的正确翻译。 - hobbes

0
你可以尝试这样做:
host = {
  'abc.com': ['fruit_apple', 'fruit_orange', 'veg_carrots'],
  '123.com': None,
  'foo.com': ['fruit_tomatoes', 'veg_potatoes']
}


print({i:[k for k in j if not k.startswith('fruit_')] if j!=None  else None for i,j in host.items() })

但如果没有None,那么您可以尝试这种有趣的方法:

print(dict(map(lambda z,y:(z,list(filter(lambda x:not x.startswith('fruit_'),host[y]))),host,host)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接