我有一个CSV文件,我正在迭代作为词典列表(想象一个excel文件中的每一行由一个由列名和该列的值组成的单个词典表示)。
有什么方法可以遍历所有词典,搜索特定的键:值组合,如果找到,删除整个词典?基本上,如果特定列== 99999,则删除行(字典)。
这就是我所拥有的,并且我正在获得“列表索引超出范围”错误 与此类事物相同。
for i in range(len(csv_data)):
column_name = 'specific_column'
if csv_data[i][column_name] == '99999':
del csv_data[i]
else:
pass
答案 0 :(得分:5)
您可以使用列表解析重建列表,保留行:
column_name = 'specific_column'
csv_data = [row for row in csv_data if row[column_name] != '99999']
这将创建一个新列表,替换旧列表,其中只保留特定列不设置为'99999'
的词典。
您收到IndexError
个异常,因为您的循环没有考虑到列表越来越短;您正在从0循环到N
,但在删除时,列表的最后一个索引从N - 1
移动到N - 2
等。
此外,当您的i
遍历索引时,您最终跳过行,i
递增,但列表中的下一个元素将向下移动删除前面的项目时的索引。
答案 1 :(得分:1)
问题在于,一旦删除项目,csv_data
的长度会发生变化,for
循环将迭代错误的次数。如果直接在csv_data
上进行迭代,则会出现另一个问题。在这种情况下,你不会得到一个异常,但循环会跳过一些值(实际上你的当前循环也是如此,但你没有注意到由于异常)
您可以保存索引,而不是立即删除对象,以便以后删除和删除它们:
to_be_removed = []
for i in range(len(csv_data)):
column_name = 'specific_column'
if csv_data[i][column_name] == '99999':
to_be_removed.append(i)
for i in to_be_removed:
del csv_data[i]
或者,您可以迭代副本并从原始值中删除元素:
for i, val in enumerate(list(csv_data)):
if val[column_name] = '99999':
del csv_data[i]
或者您可以构建副本并避免复制与谓词不匹配的元素:
copy = []
for val in csv_data:
if val[column_name] = '99999':
copy.append(val)