迭代并比较Python

时间:2015-08-12 09:14:54

标签: python list

我在Python中有两个列表:

checkNameArr = [['551002', 'Derek Jones'], 
                ['940874', 'Hugh Lunny'], 
                ['104741', 'Richard Plaith'], 
                ['310125', 'Aideen Toner'], 
                ['305795', 'Vikki Trench'], 
                ['218714', 'Paul Cutland'], 
                ['401741', 'Russell Smith'], 
                ['223996', 'Chloe Green'], 
                ['845216', 'Simon Fallon'], 
                ['402258', 'Chris Worth']]

queryNameArr = [['551002', 'Derek Jones'], 
                ['940874', 'Hugh Lunny'], 
                ['823085', 'Brian Deans'], 
                ['310125', 'Aideen Toner'], 
                ['571454', 'Pam Scales'], 
                ['967825', 'Una Lingus'], 
                ['401741', 'Russell Smith'], 
                ['682301', 'Hannah Jacobs'], 
                ['914774', 'Elaine Glass'], 
                ['402258', 'Chris Worth']]

我想比较每个列表中的数字值。我知道我需要遍历一个列表以将其与下一个列表的第一个值进行比较,如果找到匹配项,则将其存储在找到的列表中。如果找不到,请将该值存储在未找到的列表中。我试图用尽可能少的代码来做这件事,但这样做的后勤工作让我感到困惑。

什么是一个很好的清洁解决方案?

3 个答案:

答案 0 :(得分:2)

我会将您要检查的列表转换为set,方法是将每个内部元素转换为元组,然后迭代另一个列表并检查其元素(转换为元组)是否存在于集合中,如果所以将它添加到找到的列表中,否则将其添加到notfound列表中。

示例 -

checkNameSet = set(map(tuple, checkNameArr))
found = []
notfound = []
for i in queryNameArr:
    if tuple(i) in checkNameSet:
        found.append(i)
    else:
        notfound.append(i)

演示 -

>>> checkNameArr = [['551002', 'Derek Jones'],
...                 ['940874', 'Hugh Lunny'],
...                 ['104741', 'Richard Plaith'],
...                 ['310125', 'Aideen Toner'],
...                 ['305795', 'Vikki Trench'],
...                 ['218714', 'Paul Cutland'],
...                 ['401741', 'Russell Smith'],
...                 ['223996', 'Chloe Green'],
...                 ['845216', 'Simon Fallon'],
...                 ['402258', 'Chris Worth']]
>>>
>>> queryNameArr = [['551002', 'Derek Jones'],
...                 ['940874', 'Hugh Lunny'],
...                 ['823085', 'Brian Deans'],
...                 ['310125', 'Aideen Toner'],
...                 ['571454', 'Pam Scales'],
...                 ['967825', 'Una Lingus'],
...                 ['401741', 'Russell Smith'],
...                 ['682301', 'Hannah Jacobs'],
...                 ['914774', 'Elaine Glass'],
...                 ['402258', 'Chris Worth']]
>>>
... checkNameSet = set(map(tuple, checkNameArr))
>>> found = []
>>> notfound = []
>>> for i in queryNameArr:
...     if tuple(i) in checkNameSet:
...             found.append(i)
...     else:
...             notfound.append(i)
...
>>> found
[['551002', 'Derek Jones'], ['940874', 'Hugh Lunny'], ['310125', 'Aideen Toner'], ['401741', 'Russell Smith'], ['402258', 'Chris Worth']]
>>> notfound
[['823085', 'Brian Deans'], ['571454', 'Pam Scales'], ['967825', 'Una Lingus'], ['682301', 'Hannah Jacobs'], ['914774', 'Elaine Glass']]

如果您只想使用内部列表中的一个元素或元素子集进行比较,而不是将内部列表的完整元组存储在集合中,我们可以使用operator.itemgetter()来获取要比较的元素并单独储存。

然后单独使用,比较代码 -

import operator
checkNameSet = set(map(operator.itemgetter(0), checkNameArr))
found = []
notfound = []
for i in queryNameArr:
    if i[0] in checkNameSet:
        found.append(i)
    else:
        notfound.append(i)

示例/演示 -

>>> checkNameArr = [['551002', 'Derek Jones'],
...                 ['940874', 'Hugh Lunny'],
...                 ['104741', 'Richard Plaith'],
...                 ['310125', 'Aideen Toner'],
...                 ['305795', 'Vikki Trench'],
...                 ['218714', 'Paul Cutland'],
...                 ['401741', 'Russell Smith'],
...                 ['223996', 'Chloe Green'],
...                 ['845216', 'Simon Fallon'],
...                 ['402258', 'Chris Worth']]
>>>
>>> queryNameArr = [['551002', 'Derek Jones'],
...                 ['940874', 'Hugh Lunny'],
...                 ['823085', 'Brian Deans'],
...                 ['310125', 'Aideen Toner'],
...                 ['571454', 'Pam Scales'],
...                 ['967825', 'Una Lingus'],
...                 ['401741', 'Russell Smith'],
...                 ['682301', 'Hannah Jacobs'],
...                 ['914774', 'Elaine Glass'],
...                 ['402258', 'Chris Worth']]
>>>
... checkNameSet = set(map(operator.itemgetter(0), checkNameArr))
>>> found = []
>>> notfound = []
>>> for i in queryNameArr:
...     if i[0] in checkNameSet:
...             found.append(i)
...     else:
...             notfound.append(i)
...
>>> found
[['551002', 'Derek Jones'], ['940874', 'Hugh Lunny'], ['310125', 'Aideen Toner'], ['401741', 'Russell Smith'], ['402258', 'Chris Worth']]
>>> notfound
[['823085', 'Brian Deans'], ['571454', 'Pam Scales'], ['967825', 'Una Lingus'], ['682301', 'Hannah Jacobs'], ['914774', 'Elaine Glass']]

答案 1 :(得分:2)

matchingArr = [item for item in queryNameArr if item in checkNameArr]
notMatchingArr = [item for item in queryNameArr if not item in checkNameArr]

结果:

[['551002', 'Derek Jones'],
 ['940874', 'Hugh Lunny'],
 ['310125', 'Aideen Toner'],
 ['401741', 'Russell Smith'],
 ['402258', 'Chris Worth']]

[['823085', 'Brian Deans'],
 ['571454', 'Pam Scales'],
 ['967825', 'Una Lingus'],
 ['682301', 'Hannah Jacobs'],
 ['914774', 'Elaine Glass']]

基于集合的替代方案:

matchingArr = map(list, set(map(tuple, queryNameArr)).intersection(set(map(tuple, checkNameArr))))
notMatchingArr = map(list, set(map(tuple, queryNameArr)).difference(set(map(tuple, checkNameArr))))

listtuple的转换反之亦然有点烦人......(但需要,因为套装无法在列表上工作)。

答案 2 :(得分:1)

# first, let’s create a set of the check list to quickly check for membership
checkNameSet = set(tuple(x) for x in checkNameArr)

# create lists for matched, and unmatched names
matched = []
unmatched = []

# iterate the query names
for query in queryNameArr:
    # if the query name is in the check set, add it to matched, otherwise unmatched
    if tuple(query) in checkNameSet:
        matched.append(query)
    else:
        unmatched.append(query)
>>> matched
[['551002', 'Derek Jones'], ['940874', 'Hugh Lunny'], ['310125', 'Aideen Toner'], ['401741', 'Russell Smith'], ['402258', 'Chris Worth']]
>>> unmatched
[['823085', 'Brian Deans'], ['571454', 'Pam Scales'], ['967825', 'Una Lingus'], ['682301', 'Hannah Jacobs'], ['914774', 'Elaine Glass']]