字典列表理解 - 多个条件
list of dictionaries comprehension - multiple conditions
我对列表的多个条件有问题:
listionary = [{u'city': u'paris', u'id': u'1', u'name': u'paul'},
{u'city': u'madrid', u'id': u'2', u'name': u'paul'},
{u'city': u'berlin', u'id': u'3', u'name': u'tom'},
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
我尝试删除同时满足这两个条件的项目。
[elem for elem in listionary if (elem.get('name')!='paul' and elem.get('city')!='madrid')]
在这种情况下,如果至少满足一个条件,元素将被删除,我尝试了几种方法,有什么想法吗?
预期输出:
[{u'city': u'paris', u'id': u'1', u'name': u'paul'}
{u'city': u'berlin', u'id': u'3', u'name': u'tom'}
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
我想删除同时满足这两个条件的元素。
尝试将 and
更改为 or
。
[elem for elem in listionary if (elem.get('name')!='paul' or elem.get('city')!='madrid')]
记住de morgan's laws。非正式地:当你否定一个布尔表达式时,你必须将 and
切换为 or
除了将 "==" 切换为 "!=".
你的情况应该是这样的
[e for e in data if not (e.get('name') == 'paul' and e.get('city') == 'madrid')]
输出
[{u'city': u'paris', u'id': u'1', u'name': u'paul'},
{u'city': u'berlin', u'id': u'3', u'name': u'tom'},
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
这将检查当前元素的 name
是否为 paul
且 city
是否为 madrid
。如果两个条件都满足,外面的not
会翻转它,所以你会得到False
并且该项目将被省略。
基本上,您是在检查当前项目是否是您不想要的项目,如果是,则使 if
条件失败。
您可以使用 itemgetter
将所有值放入 tuple
中,然后进行比较:
>>> from operator import itemgetter
>>> name_and_city = itemgetter('name', 'city')
>>> [e for e in listionary if name_and_city(e) != ('paul', 'madrid')]
您的数据实际上是非常静态的。在这种情况下,您可以使用 namedtuple
来提高大数据的性能。
from collections import namedtuple
Profile = namedtuple('Profile', ['city', 'id', 'name'])
listionary = [Profile(*d) for d in listionary]
为了提高可读性,您可以将条件重构为 lambda 表达式(假设您使用的是 namedtuple
):
removed = lambda ele: \
ele.name == 'paul' or \
ele.city == 'madrid'
output = [ele for ele in listionary if not removed(ele)]
我认为这更易于维护且更具可读性,但这可能取决于谁在看它。
我对列表的多个条件有问题:
listionary = [{u'city': u'paris', u'id': u'1', u'name': u'paul'},
{u'city': u'madrid', u'id': u'2', u'name': u'paul'},
{u'city': u'berlin', u'id': u'3', u'name': u'tom'},
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
我尝试删除同时满足这两个条件的项目。
[elem for elem in listionary if (elem.get('name')!='paul' and elem.get('city')!='madrid')]
在这种情况下,如果至少满足一个条件,元素将被删除,我尝试了几种方法,有什么想法吗?
预期输出:
[{u'city': u'paris', u'id': u'1', u'name': u'paul'}
{u'city': u'berlin', u'id': u'3', u'name': u'tom'}
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
我想删除同时满足这两个条件的元素。
尝试将 and
更改为 or
。
[elem for elem in listionary if (elem.get('name')!='paul' or elem.get('city')!='madrid')]
记住de morgan's laws。非正式地:当你否定一个布尔表达式时,你必须将 and
切换为 or
除了将 "==" 切换为 "!=".
你的情况应该是这样的
[e for e in data if not (e.get('name') == 'paul' and e.get('city') == 'madrid')]
输出
[{u'city': u'paris', u'id': u'1', u'name': u'paul'},
{u'city': u'berlin', u'id': u'3', u'name': u'tom'},
{u'city': u'madrid', u'id': u'4', u'name': u'tom'}]
这将检查当前元素的 name
是否为 paul
且 city
是否为 madrid
。如果两个条件都满足,外面的not
会翻转它,所以你会得到False
并且该项目将被省略。
基本上,您是在检查当前项目是否是您不想要的项目,如果是,则使 if
条件失败。
您可以使用 itemgetter
将所有值放入 tuple
中,然后进行比较:
>>> from operator import itemgetter
>>> name_and_city = itemgetter('name', 'city')
>>> [e for e in listionary if name_and_city(e) != ('paul', 'madrid')]
您的数据实际上是非常静态的。在这种情况下,您可以使用 namedtuple
来提高大数据的性能。
from collections import namedtuple
Profile = namedtuple('Profile', ['city', 'id', 'name'])
listionary = [Profile(*d) for d in listionary]
为了提高可读性,您可以将条件重构为 lambda 表达式(假设您使用的是 namedtuple
):
removed = lambda ele: \
ele.name == 'paul' or \
ele.city == 'madrid'
output = [ele for ele in listionary if not removed(ele)]
我认为这更易于维护且更具可读性,但这可能取决于谁在看它。