说我有字典:
SELECT
SUM(IF(a.id = 1, IF(t.type = 1 AND t.charge_account = 1, t.value, 0) - IF(t.type = 0 AND t.charge_account = 1, t.value, 0), 0) + a.start-balance) as "balanc_1",
SUM(IF(a.id = 2, IF(t.type = 1 AND t.charge_account = 2, t.value, 0) - IF(t.type = 0 AND t.charge_account = 2, t.value, 0), 0) + a.start-balance) as "balance_2",
SUM(IF(a.id = 3, IF(t.type = 1 AND t.charge_account = 3, t.value, 0) - IF(t.type = 0 AND t.charge_account = 3, t.value, 0), 0) + a.start-balance) as "balance_3"
FROM test.transactions t, test.accounts a
WHERE t.paid = 1;
我有一个称为键的列表:
my_dict = [
{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'James', 'middle': 'smith', 'last': 'joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
{'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
{'first': 'James', 'middle': 'jackson', 'last': 'Harden'},
]
我想根据键中的每个值过滤myDict,这将导致
keys = ["first", "last"]
正如您在my_dict列表中的列表字典中所观察到的那样,重复的dict值从列表中删除或过滤掉,并且仅该dict实例的第一个条目被带入已过滤的输出中。
如果两个键的值相同,则需要删除重复项。
在Python中使用字典/列表理解是否有一种简便的方法?还有另一种更快的方法可以实现这一目标吗?
答案 0 :(得分:3)
您可以使用key
来使用itertools.groupby
(x["first"].lower, x["last"].lower())
进行分组,然后仅分组分组值的第0个元素:
from itertools import groupby
# https://docs.python.org/3/library/itertools.html#itertools.groupby
my_dict = [
{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'James', 'middle': 'smith', 'last': 'joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
{'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
{'first': 'James', 'middle': 'jackson', 'last': 'Harden'},
]
keys = ["first","last"]
k = [list(data)[0] for key,data in groupby(my_dict,
key=lambda x: tuple(x[i].lower() for i in keys))]
print(k)
输出:
[{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'}]
注意事项:
Groupby仅适用于连续键-如果列表末尾有第三个{'first': 'James', 'middle': 'Smith', 'last': 'JOUle'}
,他会得到它自己的条目:
制作一个迭代器,该迭代器从 iterable
返回连续键和组 (来自doku,上方链接)
如果您希望将它们全部归入同一组,则需要先对列表进行分组,然后再对其进行排序。
答案 1 :(得分:2)
首先,将其命名为my_list
,而不是my_dict
。
my_list = [
{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'James', 'middle': 'smith', 'last': 'joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
{'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
{'first': 'James', 'middle': 'jackson', 'last': 'Harden'}
]
keys = ["first", "last"]
然后,您可以通过以下理解实现您的目标:
import collections
temp = collections.OrderedDict([
(
tuple(e[k].lower() for k in keys), # only some keys will determine duplicates
e,
)
for e in my_list])
my_new_list = list(temp.values())
通过按姓氏和姓氏对元素进行分组,将排除重复项。以后,如果需要,只需要将其再次投射到列表中即可。
使用OrderedDict
可以保留原始顺序。
我还使用.lower()
查找不区分大小写的重复项。
答案 2 :(得分:1)
以下解决方案不需要任何import语句,并且可以区分大小写。它还仅考虑键列表中提供的字段,并且在匹配时忽略所有其他字段(the solution provided by Mstaino会在匹配时将所有字段都考虑在内,无论您的键列表中可能包含什么)。
my_dict = [
{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'James', 'middle': 'smith', 'last': 'joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
{'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
{'first': 'James', 'middle': 'jackson', 'last': 'Harden'},
]
keys = ["first","last"]
fields = [''.join([x.lower() for x in \
list(map(lambda x : my_dict[i].__getitem__(x), keys))]) \
for i,v in enumerate(my_dict)]
filtered_dict = [my_dict[i] for i,v in enumerate(fields) if fields.index(v) == i]
如果只想消除连续的重复(如the solution provided by Patrick Artner中的重复),则必须以以下方式声明filtered_dict
:
filtered_dict = [ my_dict[i] for i,v in enumerate(fields) if i == 0 or v != fields[i-1] ]
答案 3 :(得分:0)
一种解决方案是使用如下所示的pandas数据框。这样可以非常像CSV文件一样删除重复的行。但是,这没有考虑区分大小写,如果需要区分大小写的重复删除,那将是另一种方法。但这工作得很好。
import pandas as pd
my_dict = [
{'first': 'James', 'middle': 'Smith', 'last': 'Joule'},
{'first': 'James', 'middle': 'smith', 'last': 'joule'},
{'first': 'Christian', 'middle': 'Edward', 'last': 'Doppler'},
{'first': 'Robert', 'middle': 'Edward', 'last': 'Antonio'},
{'first': 'Robert', 'middle': 'edward', 'last': 'antonio'},
{'first': 'Robert', 'middle': 'edwrd', 'last': 'Antonio'},
{'first': 'James', 'middle': 'Jackson', 'last': 'harden'},
{'first': 'James', 'middle': 'jackson', 'last': 'Harden'}
]
keys = ["first", "last"]
df = pd.DataFrame(my_dict)
df = df.drop_duplicates(keep="first")
print(df)
答案 4 :(得分:0)
首先,请确定您要过滤不区分大小写的邮件。
用于过滤上下限的python解决方案:
values = list(map(lambda x: set(i.lower() for i in x.values()), my_dict))
my_filter_list = [my_dict[i] for i,x in enumerate(values) if values.index(x)==i]