Python 打印列表中每行已更改列的索引

Python 打印列表中每行已更改列的索引,python,list,Python,List,下面的循环通过两个列表(源和主列表)扫描匹配的ID(索引0),然后对于ID匹配的行,它会查找已更改的列并打印它们: for row in source: identifier = row[0] new_cols = row[1:] for row in master: old_cols = row[1:] if identifier == row

下面的循环通过两个列表(源和主列表)扫描匹配的ID(索引0),然后对于ID匹配的行,它会查找已更改的列并打印它们:

        for row in source:
            identifier = row[0]
            new_cols = row[1:]
            for row in master:
                old_cols = row[1:]
                if identifier == row[0]:
                    print(row[0]) # ID that matched
                    changed_cols = [col for col in new_cols if col not in old_cols] 
                    print(changed_cols) # cols that differ
列表每行包含20多列,因此我认为使用行[1:]会很明智,但我不确定如何使用此方法获取更改的列的索引。谢谢你的帮助

更新:

source = [['1002', '', '', '', '13RA11', '', 'LO', '4302', '99111', '0', ''], 
['1076', '', '', '', '13RA11', '', 'LO', '4302', '999111', '0', ''], 
['1130', '', '', '', '11HOT1A', '', 'LO', '4302', '99111', '0', '']]

master = [['1002', '', '', '', '13RA11', '', 'LO', '4302', '99111', '0', ''], 
['1076', '', '', '', '13RA11', '', 'LO', '4302', '999111', '1', ''], 
['1130', '', '', '', '13RA11', '', 'LO', '4302', '99111', '1', '']]

尝试创建一个过滤器,并使用
zip
将每个匹配行折叠在一起(即,将源代码和主代码中具有匹配ID的行压缩在一起。)

对于
source_row1=[1,6,3,8],master_row1=[5,6,7,8]
这将打印索引1和索引3。如果你愿意,你也可以把整个事情放在一个列表中,如下所示:

changed_cols = [enum for enum, item in enumerate(bool_gen(zip(source_row1, master_row1))) if (item == True)]
# changed_cols returns [1, 3]

将此建议用于您的代码:

for row in source:
    identifier = row[0]
    new_cols = row[1:]
    for row in master:
        old_cols = row[1:]
        if identifier == row[0]:
            print(row[0]) # ID that matched
            changed_cols = [enum for enum, item in enumerate(bool_gen(zip(new_cols, old_cols))) if (item == True)]
            print(changed_cols) # cols that differ
但是,正如您所看到的,它既不能减少所需的代码量,也不能提高可读性。我不确定哪种代码更有效


如果我们的答案不正确,请告诉我们。如果是,请在问题中添加更多详细信息。

您是否考虑过使用
枚举
?您的列表理解将更改为:

changed_cols = [(ID,col) for ID,col in enumerate(new_cols) if col not in old_cols]
对我来说,这似乎是最简单的解决办法

如果我误解了您的问题,请告诉我,我将努力调整我的解决方案:)

编辑:我想你可能想要加里建议的东西:

changed_cols = [(ID,col) for ID,col in enumerate(new_cols) if col != old_cols[ID]]

这将仅比较每个新列对应的旧列。我猜这就是你真正想要的功能。如果您不确定差异,请告诉我:)

您应该保留列号以进行比较。如果不这样做,则不会检测到两列之间的交换。你可以做:

for row in source:
    identifier = row[0]
    new_cols = row[1:]
    for row in master:
        if identifier == row[0]:
            old_cols = row[1:]
            print(row[0]) # ID that matched
            n = len(new_cols) if len(new_cols) <= len(old_cols) else len(old_cols)
            changed_cols = [(i, old_cols[i], new_col[i]) for i in range(n) if new_cols[i] != old_cols[i ]] 
            print(changed_cols) # cols that differ
            if len(new_cols) < len(old_cols): print(len(old_cols)-len(new_cols), " cols missing")
            if len(new_cols) > len(old_cols): print(len(new_cols)-len(old_cols), " cols added")
对于源中的行:
标识符=行[0]
新列=行[1:]
对于主控中的行:
如果标识符==行[0]:
old_cols=行[1:]
打印(第[0]行)#匹配的ID
n=len(新列)如果len(新列)len(旧列):打印(len(新列)-len(旧列),“添加列”)

我对您想要实现的目标有点困惑。给定源行
[1,0,0,0]
和相应的主行
[1,0,0,1]
,您的代码(以及我的答案中的代码)将不会拾取任何“已更改的列”。你确定这就是你想要的吗?或者你想要加里贴的东西?嗯。。。您可能必须小心该行中的重复条目。请记住,如果
col
在列表中的任何位置
old\u cols
,则条件
col not in old\u cols
将为false。这是你想要的吗?我将为我的解决方案添加一个可能是您实际需要的替代方案。此代码的功能与OP使用的列表不同。虽然这似乎更有意义。谢谢!您的解决方案使我对整个过程有了更好的了解(很高兴我们能提供帮助:)
for row in source:
    identifier = row[0]
    new_cols = row[1:]
    for row in master:
        if identifier == row[0]:
            old_cols = row[1:]
            print(row[0]) # ID that matched
            n = len(new_cols) if len(new_cols) <= len(old_cols) else len(old_cols)
            changed_cols = [(i, old_cols[i], new_col[i]) for i in range(n) if new_cols[i] != old_cols[i ]] 
            print(changed_cols) # cols that differ
            if len(new_cols) < len(old_cols): print(len(old_cols)-len(new_cols), " cols missing")
            if len(new_cols) > len(old_cols): print(len(new_cols)-len(old_cols), " cols added")