如何根据 Python 列表中存在的值从列表中删除字典?
How do I remove a dictionary from a list depending on a value being present in a list in Python?
我是 Python 的新手,如果我的代码没有以最 'pythonic' 的方式编写,请提前致歉。
我正在将 CSV 文件上传到脚本,如果该行符合特定条件,我想过滤该 CSV。
我有两个列表,a_lst
和 b_lst
。一旦字典在 a_lst
中,我就会检查 b_lst
中是否有对应 key:value 的字典。如果有匹配项,则会将其打印到控制台。我不想打印到控制台,而是想从 a_lst
中删除该项目。我该怎么做?
a_lst = []
b_lsts = []
with open(file_name, 'rt') as f:
reader = csv.DictReader(f)
for row in reader:
if row['Minutes'] == '0' and row['MB'] == '0' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '0' and row['MB'] == '' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '' and row['MB'] == '0' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '' and row['MB'] == '' and row['Calls'] == '1':
a_lst.append(row)
else:
b_lst.append(row)
i = 0
while i < len(a_lst):
if not any(d['Name'] == a_lst[i]['Name'] for d in b_lst):
print a_lst[i]['Name']+"(Row"+str(i)+") is not b_lst."
else:
print a_lst[i]['Name']+"(Row"+str(i)+") is present."
i+=1
编辑:我想要的结果
Name, PhoneNo, Minutes, MB, Calls
Steve,0777777777,0,0,1
Steve,0777777777,0,2,14
Steve,0777777777,0,0,1
John,078888888,0,0,1
John,078888888,0,0,1
John,078888888,0,0,1
Dave,07999999,2,3,4
Dave,07999999,2,6,24
如果上面的数据是我插入的,我只想看到 John
的名字,因为他是唯一一个他的名字的所有行都包含值“0,0,1”的人'
如果元素具有相同的 key/value,只需从列表中删除该元素,您还想在 any
之前删除 not
,因为如果有任何匹配,我们要删除:
for ele in a_lst[:]:
if any(d['Name'] == ele['Name'] for d in b_lst):
a_lst.remove(ele)
或者在添加之前忘记使用 any
和过滤器,将 row['Name']
添加到集合中并检查我们是否已经看到它:
seen = set()
with open(file_name, 'rt') as f:
reader = csv.DictReader(f)
for row in reader:
if row['Name'] in seen:
continue
if all((row['Minutes'] == '0', (row['MB'] == '0' or not row['MB']), row['Calls'] == '1')):
a_lst.append(row)
elif all((not row['Minutes'], (row['MB'] or not row['MB']), row['Calls'] == '1')):
a_lst.append(row)
else:
seen.add(row['Name'])
# remove "else:" and just use seen.add(row['Name']) outside the elif if you want all dups removed
根据您的编辑:
seen = set()
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
for row in reader:
if row[0] in seen:
continue
if all(x in {"0", "1"} for x in row[2:]):
print(row)
seen.add(row[0])
输出:
['Steve', '0777777777', '0', '0', '1']
['John', '078888888', '0', '0', '1']
Steve
和 John
的相关列中只有 0 和 1。
如果您只想要列中仅包含 0 和 1 的名称:
from collections import defaultdict
d = defaultdict(list)
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
for row in reader:
d[row[0]].append([row, set(row[2:])])
print([v[0][0] for k, v in d.items() if all(sub[1] == {"0","1"} for sub in v)])
[['John', '078888888', '0', '0', '1']]
或者如果您的名字总是组合在一起,则使用集合:
seen = set()
temp = set()
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
next(reader)
prev = None
for row in reader:
# found new name and it is not the first
if row[0] not in seen and temp:
# set should only hav and 1 if all columns only contain 0,1
if temp == {"0", "1"}:
print(prev) # print previous row
# reset temp
temp = set()
seen.add(row[0])
temp.update(row[2:])
# need to keep track of previous row
prev = row
输出:
['John', '078888888', '0', '0', '1']
我是 Python 的新手,如果我的代码没有以最 'pythonic' 的方式编写,请提前致歉。
我正在将 CSV 文件上传到脚本,如果该行符合特定条件,我想过滤该 CSV。
我有两个列表,a_lst
和 b_lst
。一旦字典在 a_lst
中,我就会检查 b_lst
中是否有对应 key:value 的字典。如果有匹配项,则会将其打印到控制台。我不想打印到控制台,而是想从 a_lst
中删除该项目。我该怎么做?
a_lst = []
b_lsts = []
with open(file_name, 'rt') as f:
reader = csv.DictReader(f)
for row in reader:
if row['Minutes'] == '0' and row['MB'] == '0' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '0' and row['MB'] == '' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '' and row['MB'] == '0' and row['Calls'] == '1':
a_lst.append(row)
elif row['Minutes'] == '' and row['MB'] == '' and row['Calls'] == '1':
a_lst.append(row)
else:
b_lst.append(row)
i = 0
while i < len(a_lst):
if not any(d['Name'] == a_lst[i]['Name'] for d in b_lst):
print a_lst[i]['Name']+"(Row"+str(i)+") is not b_lst."
else:
print a_lst[i]['Name']+"(Row"+str(i)+") is present."
i+=1
编辑:我想要的结果
Name, PhoneNo, Minutes, MB, Calls
Steve,0777777777,0,0,1
Steve,0777777777,0,2,14
Steve,0777777777,0,0,1
John,078888888,0,0,1
John,078888888,0,0,1
John,078888888,0,0,1
Dave,07999999,2,3,4
Dave,07999999,2,6,24
如果上面的数据是我插入的,我只想看到 John
的名字,因为他是唯一一个他的名字的所有行都包含值“0,0,1”的人'
如果元素具有相同的 key/value,只需从列表中删除该元素,您还想在 any
之前删除 not
,因为如果有任何匹配,我们要删除:
for ele in a_lst[:]:
if any(d['Name'] == ele['Name'] for d in b_lst):
a_lst.remove(ele)
或者在添加之前忘记使用 any
和过滤器,将 row['Name']
添加到集合中并检查我们是否已经看到它:
seen = set()
with open(file_name, 'rt') as f:
reader = csv.DictReader(f)
for row in reader:
if row['Name'] in seen:
continue
if all((row['Minutes'] == '0', (row['MB'] == '0' or not row['MB']), row['Calls'] == '1')):
a_lst.append(row)
elif all((not row['Minutes'], (row['MB'] or not row['MB']), row['Calls'] == '1')):
a_lst.append(row)
else:
seen.add(row['Name'])
# remove "else:" and just use seen.add(row['Name']) outside the elif if you want all dups removed
根据您的编辑:
seen = set()
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
for row in reader:
if row[0] in seen:
continue
if all(x in {"0", "1"} for x in row[2:]):
print(row)
seen.add(row[0])
输出:
['Steve', '0777777777', '0', '0', '1']
['John', '078888888', '0', '0', '1']
Steve
和 John
的相关列中只有 0 和 1。
如果您只想要列中仅包含 0 和 1 的名称:
from collections import defaultdict
d = defaultdict(list)
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
for row in reader:
d[row[0]].append([row, set(row[2:])])
print([v[0][0] for k, v in d.items() if all(sub[1] == {"0","1"} for sub in v)])
[['John', '078888888', '0', '0', '1']]
或者如果您的名字总是组合在一起,则使用集合:
seen = set()
temp = set()
with open(infile, 'rt') as f:
reader = csv.reader(f,delimiter=",")
next(reader)
prev = None
for row in reader:
# found new name and it is not the first
if row[0] not in seen and temp:
# set should only hav and 1 if all columns only contain 0,1
if temp == {"0", "1"}:
print(prev) # print previous row
# reset temp
temp = set()
seen.add(row[0])
temp.update(row[2:])
# need to keep track of previous row
prev = row
输出:
['John', '078888888', '0', '0', '1']