简体   繁体   English

迭代和比较Python中的列表列表

[英]Iterating and comparing list of lists in Python

I have 2 lists in Python: 我在Python中有2个列表:

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

And I would like to compare the number value in each list. 我想比较每个列表中的数字值。 I know that I would need to iterate through one list to compare it to the first value of the next list, if a match is found, store it in a found list. 我知道我需要遍历一个列表以将其与下一个列表的第一个值进行比较,如果找到匹配项,则将其存储在找到的列表中。 If it isn't found, store that value in a not found list. 如果找不到,则将该值存储在“找不到”列表中。 I am trying to do this in the smallest amount of code possible but the logistics of this are confusing me. 我正在尝试以尽可能少的代码来执行此操作,但是这样做的后勤使我感到困惑。

What would be a nice clean solution? 有什么好的清洁解决方案?

I would convert the list in which you want to check to set by converting each inner element to tuple and then iterate over the other list and check if its element (converted to tuple) exists in the set, if so add it to found list, else add it to notfound list. 我会在其中要检查的列表转换set每个内部元件转换成元组,然后遍历另一张单子,检查其元(换算成元组)中设定的存在,如果是将其添加到发现列表中,否则将其添加到未找到的列表。

Example - 范例-

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

Demo - 演示-

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

If you only want to compare using one element or a subset of elements of the inner list, instead of storing the complete tuple of inner list in the set, we can use operator.itemgetter() to get just the element to compare and store that alone. 如果您只想使用内部列表的一个元素或元素的子集进行比较,而不是将内部列表的完整元组存储在集合中,则可以使用operator.itemgetter()来获取要比较并存储该元素的元素单独。

And then compare using that alone , Code - 然后单独比较,代码-

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)

Example/Demo for this - 示例/演示-

>>> 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']]
matchingArr = [item for item in queryNameArr if item in checkNameArr]
notMatchingArr = [item for item in queryNameArr if not item in checkNameArr]

Result: 结果:

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

An alternative based on sets: 基于集的替代方法:

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

The conversion from list to tuple and vice versa is somewhat annoying... (but needed, because sets can't work on lists). listtuple ,反之亦然的转换有点烦人……(但有必要,因为集合不能在列表上使用)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM