以下循环扫描匹配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', '']]
答案 0 :(得分:1)
尝试创建过滤器并使用zip
将每个匹配的行折叠在一起(例如,将源和主行中的行压缩在一起,以匹配ID。)
# A generator that returns True/False based on items matching.
def bool_gen(zipped):
for tup in zipped:
yield tup[0] == tup[1]
# Use enumerate to store columns as you iterate over the generator.
for enum, item in enumerate(bool_gen(zip(source_row1, master_row1))):
if (item == True):
# Print the matching index.
print(enum)
对于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
但是,正如您所看到的,它不会减少所需的代码量,也不会使其更具可读性。我不确定哪个代码会更有效率。
如果我们的答案不合适,请告诉我们。如果是这样,请在问题中添加更多详细信息。
答案 1 :(得分:1)
您是否考虑过使用enumerate
?您的列表理解将改为:
changed_cols = [(ID,col) for ID,col in enumerate(new_cols) if col not in old_cols]
这对我来说似乎是最简单的解决方案。
如果我误解了您的问题,请告诉我,我会努力调整我的解决方案:)
编辑:我想你可能想要像Gary建议的那样:
changed_cols = [(ID,col) for ID,col in enumerate(new_cols) if col != old_cols[ID]]
这将仅比较每个新列的相应旧列。我猜这是你真正想要的功能。如果您不确定区别,请告诉我:))
答案 2 :(得分:1)
您应该保留列号以进行比较。如果不这样做,则不会检测到2列之间的交换。你可以这样做:
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")