2016-01-15 38 views
4

我与列表中的多个条件的一个问题:列表 - 多个条件

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'}] 

我想删除满足这两个条件的元素。

+0

预期产量是多少? – thefourtheye

回答

5

尝试改变andor

[elem for elem in listionary if (elem.get('name')!='paul' or elem.get('city')!='madrid')] 

还记得de morgan's laws。非正式地说:当您取消布尔表达式时,除了使用“!=”切换“==”之外,还必须切换andor

+0

太棒了,这正是我一直在寻找的。基本的逻辑错误,很好知道。非常感谢 – causeyo

5

你的情况应该是这样的

[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'}] 

此检查当前元素的namepaulcitymadrid。如果两个条件都满足,外部的not将翻转它,所以你会得到False,该项目将被省略。

基本上你是检查,如果当前项目是你不想做出如果是if条件失败之一。

+0

@causeyo请考虑[接受一个答案(http://meta.stackexchange.com/a/5235/235416),从而使未来的读者都知道,这个问题得到解决,解决的办法是可靠的: - ) – thefourtheye

2

你可以使用itemgetter让所有的值到一个tuple,然后比较认为:

>>> from operator import itemgetter 
>>> name_and_city = itemgetter('name', 'city') 
>>> [e for e in listionary if name_and_city(e) != ('paul', 'madrid')] 
1

您的数据其实相当静态的。在这种情况下,您可以使用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)] 

我觉得这是更容易维护和更具可读性,但它可能取决于谁在看它。