验证列表中的列表是否匹配python中另一个列表的值

时间:2018-02-04 02:45:29

标签: python list

我有一个列表列表(包含数万个子列表)。 及时,用户可以将更多列表添加到大列表中。

作为一个模拟示例,我有类似的东西:

my_list_grouped_by_0 = 
    [['X00001', 1123477, 1.25, 'Yes', 'No', 11.53, 3.23, 0.25], 
     ['X00002', 1125251, 0.22, 'Yes', 'No', 22.83, 3.6, 0.5], 
     ['X00003', 1125433, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15], 
     ['X00004', 1231254, 1.3, 'Yes', 'No', 21.83, 3.6, 0.5], 
     ['X00008', 2520250, 54.02, 'Yes', 'No', 1.83, 3.8, 0.01], 
     ['X00005', 3202020, 966.33, 'Yes', 'No', 1.8, 3.8, 0.36], 
     ['X00006', 3215204, 1.36, 'Yes', 'No', 1.86, 3.65, 0.15], 
     ['X00007', 4561230, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1], 
     ['X00009', 5721365, 1.25, 'No', 'No', 11.53, 3.23, 0.25], 
     ['X00010', 8520025, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1], 
     ['X00012', 8520123, 966.33, 'Yes', 'No', 1.8, 3.8, 0.36], 
     ['X00011', 9536122, 54.01, 'Yes', 'No', 1.83, 3.8, 0.01], 
     ['X00015', 1212021, 0.333, 'No', 'No', 1.83, 3.8, 0.01], 
     ['X00013', 9654123, 4.1, 'No', 'No', 1.83, 3.8, 0.01], 
     ['X00014', 2021230, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15], 
     ['X00017', 3322123, 1.23, 'Yes', 'Yes', 1.88, 1.25, 1.12], 
     ['X00016', 9531450, 23.15, 'Yes', 'Yes', 1.83, 3.25, 0.12], 
     ['X00020', 3625252, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15], 
     ['X00018', 1205203, 1.87, 'Yes', 'No', 1.88, 1.25, 1.12], 
     ['X00019', 1124521, 0.25, 'No', 'No', 2.1, 0.6, 0.03], 
     ['X00021', 8952631, 0.25, 'No', 'No', 2.4, 0.6, 0.03], 
     ['X00022', 1123458, 0.33, 'Yes', 'Yes', 10.38, 41.11, 0.5], 
     ['X00023', 3236254, 3, 'No', 'Yes', 10.38, 41.11, 0.5], 
     ['X00024', 1205323, 1.87, 'Yes', 'No', 1.88, 1.25, 1.12]] 

用户将添加新列表,例如:

['X00099', 1212021, 0.333, 'No', 'No', 1.83, 3.8, 0.01]

如果索引2,3,4,5,6,7处的值与现有列表列表中的一个列表匹配,我希望索引0处的值(在本例中为X00099)被原始列表中的值(在本例中为' X00015',因为值匹配)。

如果新列表与任何现有列表都不匹配,我想添加下一个X00000值(在这种情况下,添加到新添加的列表中我将分配X00025。

索引1处的值是每个列表唯一的Id,仅用于将信息覆盖回数据库,确认具有相应Id的列表与其他列表的值相同。

我不知道如何将新添加的列表与原始列表列表中的列表进行比较,看看是否匹配任何内容或是新内容。

但是,我可以使用groupby:

from itertools import groupby
from operator import itemgetter

得到这个:

>>> my_list_grouped_by = [list(g) for _, g in groupby(sorted(my_list), itemgetter(2, 3, 4, 5, 6, 7))]
>>> my_list_grouped_by
[[['X0000', 1123477, 1.25, 'Yes', 'No', 11.53, 3.23, 0.25]], 
[['X0000', 1125251, 0.22, 'Yes', 'No', 22.83, 3.6, 0.5]], 
[['X0000', 1125433, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15]], 
[['X0000', 1231254, 1.3, 'Yes', 'No', 21.83, 3.6, 0.5]], 
[['X0000', 2520250, 54.02, 'Yes', 'No', 1.83, 3.8, 0.01]], 
[['X0000', 3202020, 966.33, 'Yes', 'No', 1.8, 3.8, 0.36]], 
[['X0000', 3215204, 1.36, 'Yes', 'No', 1.86, 3.65, 0.15]], 
[['X0000', 4561230, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1], 
['X0000', 5252631, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1]], 
[['X0000', 5721365, 1.25, 'No', 'No', 11.53, 3.23, 0.25], 
['X0000', 7721365, 1.25, 'No', 'No', 11.53, 3.23, 0.25]], 
[['X0000', 8520025, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1]], 
[['X0000', 8520123, 966.33, 'Yes', 'No', 1.8, 3.8, 0.36]], 
[['X0000', 9536122, 54.01, 'Yes', 'No', 1.83, 3.8, 0.01]], 
[['X0010', 1212021, 0.333, 'No', 'No', 1.83, 3.8, 0.01]], 
[['X0010', 9654123, 4.1, 'No', 'No', 1.83, 3.8, 0.01]], 
[['X0020', 2021230, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15]], 
[['X0070', 3322123, 1.23, 'Yes', 'Yes', 1.88, 1.25, 1.12]], 
[['X0070', 9531450, 23.15, 'Yes', 'Yes', 1.83, 3.25, 0.12]], 
[['X0303', 3625252, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15],
['X0333', 3625257, 1.23, 'Yes', 'No', 1.86, 3.65, 0.15]], 
[['X0670', 1205203, 1.87, 'Yes', 'No', 1.88, 1.25, 1.12]], 
[['X1070', 1124521, 0.25, 'No', 'No', 2.1, 0.6, 0.03], 
['X1070', 3302145, 0.25, 'No', 'No', 2.1, 0.6, 0.03]], 
[['X1070', 8952631, 0.25, 'No', 'No', 2.4, 0.6, 0.03]], 
[['X3330', 1123458, 0.33, 'Yes', 'Yes', 10.38, 41.11, 0.5]], 
[['X3330', 3236254, 3, 'No', 'Yes', 10.38, 41.11, 0.5]], 
[['X8670', 1205323, 1.87, 'Yes', 'No', 1.88, 1.25, 1.12]]]
>>>

然后我可以循环并用该组的第一个成员覆盖X00000,但这并不能保证X00000将是现有列表列表中的一个。

保留原始X号对于此任务至关重要。

任何建议或指出类似的解决方案,非常感谢。

非常感谢您寻求帮助!

2 个答案:

答案 0 :(得分:0)

您可以创建相关列的索引(类似于DB索引)并将其用于查找。

使用一些伪代码,这可能如下所示:

indexed = {tuple(entry[2:8]): idx for idx, entry in enumerate(my_list_grouped_by_0)}

def add_new(newEntry):
    col0 = indexed.get(tuple(newEntry[2:8]))

    if col0 is None:
        <Assign new id to col0>

    my_list_grouped_by_0.append([col0] + newEntry[1:])

    <Add new entry to index if necessary>

答案 1 :(得分:0)

直观的解决方案是使用生成器理解和列表切片,如下所示:

new = ['X00025', 8520025, 6.33, 'Yes', 'No', 1.83, 66.22, 0.1]  # same as X00010

new[1:] in (elem[1:] for elem in my_list_grouped_by_0))  # returns True because of X00010

但是,如果性能很重要,我无法保证此解决方案的相对速度。

修改

这将是一个函数的示例,它不仅检查匹配,还会进行更新。

def add_to_big_list(new):
    for old in my_list_grouped_by_0:
        if new[1:] == old[1:]:
            # A match was found so we replace the ID.
            old[0] = new[0]
            return
    # No match was found so we add the new entry.
    my_list_grouped_by_0.append(new)