我有一个字典列表,其中包含一些重复的ID,我想将具有值的字典保留在rsrp下,并删除那些具有0的字典,但是如果存在重复的字典,并且两次的rsrp为0我需要保留它。
下面是当前和所需的列表示例,有没有简单的方法可以做到这一点?通过循环查找非“ 0”很容易,但是如果匹配的ID为“ 0”,则不确定
current_list = [
{'id': 255, 'rssi': -108.0},
{'id': 255, 'rssi': '0'},
{'id': 301, 'rssi': -82.0},
{'id': 301, 'rssi': '0'},
{'id': 263, 'rssi': -85.0},
{'id': 263, 'rssi': '0'},
{'id': 18, 'rssi': '0'},
{'id': 18, 'rssi': '0'}
]
desired_list = [
{'id': 255, 'rssi': -108.0},
{'id': 301, 'rssi': -82.0},
{'id': 263, 'rssi': -85.0},
{'id': 18, 'rssi': '0'}
]
答案 0 :(得分:3)
itertools recipes中有一种称为unique_everseen
的方法:
from itertools import filterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
您可以使用它来获取所需的列表:
desired_list = list(unique_everseen(current_list, key=lambda x: x["rssi"]))
# [{'id': 255, 'rssi': -108.0}, {'id': 255, 'rssi': '0'},
# {'id': 301, 'rssi': -82.0}, {'id': 263, 'rssi': -85.0}]
剩下要做的就是使用'rssi'
的{{1}}参数选择key
。
答案 1 :(得分:2)
使用简单的迭代。
例如:
current_list = [
{'id': 255, 'rssi': -108.0},
{'id': 255, 'rssi': '0'},
{'id': 301, 'rssi': -82.0},
{'id': 301, 'rssi': '0'},
{'id': 263, 'rssi': -85.0},
{'id': 263, 'rssi': '0'},
{'id': 18, 'rssi': '0'},
{'id': 18, 'rssi': '0'}
]
seen = set()
result = []
for i in sorted(current_list, key=lambda x: True if x["rssi"] == "0" else False):
if (i["id"] not in seen and i["rssi"] != "0") or \
(i["id"] not in seen and i["rssi"] == "0"):
result.append(i)
seen.add(i["id"])
输出:
[{'id': 255, 'rssi': -108.0},
{'id': 301, 'rssi': -82.0},
{'id': 263, 'rssi': -85.0},
{'id': 18, 'rssi': '0'}]
答案 2 :(得分:0)
如果您可以在项目中使用外部库,则可以利用Pandas向量化操作。
例如:
import pandas as pd
df = pd.DataFrame(current_list)
df["rssi"] = pd.to_numeric(df["rssi"])
df = df[(df["rssi"] != 0) | (df.groupby("id").transform("min") == 0)["rssi"]]
df = df.drop_duplicates()
df.to_dict("records")
答案 3 :(得分:0)
使用itertools.groupby
的一种解决方案。如果只有rssi
个0
项,我们保留一个。我们将所有其他非零rssi
项添加到输出列表:
current_list = [
{'id': 255, 'rssi': -108.0},
{'id': 255, 'rssi': '0'},
{'id': 301, 'rssi': -82.0},
{'id': 301, 'rssi': '0'},
{'id': 263, 'rssi': -85.0},
{'id': 263, 'rssi': '0'},
{'id': 18, 'rssi': '0'},
{'id': 18, 'rssi': '0'}
]
from itertools import groupby
out = []
for v, g in groupby(sorted(current_list, key=lambda k: (k['id'], k['rssi'] == '0')), lambda k: k['id']):
out.append(next(g)) # ensure we add at least one `0`
out.extend(i for i in g if i['rssi'] != '0') # add any non-zero `rssi` items
from pprint import pprint
pprint(out)
打印:
[{'id': 18, 'rssi': '0'},
{'id': 255, 'rssi': -108.0},
{'id': 263, 'rssi': -85.0},
{'id': 301, 'rssi': -82.0}]
答案 4 :(得分:0)
如果不使用任何import
,我将按照以下方式进行操作:
current_list = [
{'id': 255, 'rssi': -108.0},
{'id': 255, 'rssi': '0'},
{'id': 301, 'rssi': -82.0},
{'id': 301, 'rssi': '0'},
{'id': 263, 'rssi': -85.0},
{'id': 263, 'rssi': '0'},
{'id': 18, 'rssi': '0'},
{'id': 18, 'rssi': '0'}
]
output = {}
for i in current_list:
if not i['id'] in output:
output[i['id']] = []
output[i['id']].append(i['rssi'])
# now output is {255: [-108.0, '0'], 301: [-82.0, '0'], 263: [-85.0, '0'], 18: ['0', '0']}
def func(x):
for j in x:
if j!='0':
return j
return '0'
desired_list = [{'id':i[0],'rssi':func(i[1])} for i in output.items()]
print(desired_list)
输出:
[{'id': 255, 'rssi': -108.0}, {'id': 301, 'rssi': -82.0}, {'id': 263, 'rssi': -85.0}, {'id': 18, 'rssi': '0'}]