2016-01-15 63 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)] 

我覺得這是更容易維護和更具可讀性,但它可能取決於誰在看它。