我有一个包含三个这样的参数的列表: -
[(8L, 'Mail Opened', 'Saturday'), (4L, 'Mail Not Opened', 'Saturday'), (2L, 'Mail Not Opened', 'Sunday'), (8L, 'Mail Opened', 'Sunday'), (1L, 'Mail Not Opened', 'Monday'), (12L, 'Mail Opened', 'Monday'), (10L, 'Mail Opened', 'Tuesday'), (4L, 'Mail Not Opened', 'Tuesday'), (14L, 'Mail Opened', 'Wednesday'), (6L, 'Mail Not Opened', 'Wednesday'), (1L, 'Mail Not Opened', 'Thursday'), (19L, 'Mail Opened', 'Thursday'), (28L, 'Mail Opened', 'Friday'), (1L, 'Mail Opened', 'Friday')]
我可以得到这样的结果
[("Saturday",8,4)],[("Sunday",8,2)]
这里我根据DAYNAME结合了两个元组。我把“Mail Opened”值放在第一位,“Mail not open value”放在第二位。也可能存在只有一个值可能存在的情况 列表看起来像
[("Saturday",0,4)],[("Sunday",8,0)]
请帮帮我
答案 0 :(得分:2)
您使用tuple
作为dict
,使用字典(或本例中为defaultdict
)会更简单。
看看:
from collections import defaultdict
lst = [(8L, 'Mail Opened', 'Saturday'), (4L, 'Mail Not Opened', 'Saturday'), (2L, 'Mail Not Opened', 'Sunday'), (8L, 'Mail Opened', 'Sunday'), (1L, 'Mail Not Opened', 'Monday'), (1L, 'Mail Not Opened', 'Monday'), (12L, 'Mail Opened', 'Monday'), (10L, 'Mail Opened', 'Tuesday'), (4L, 'Mail Not Opened', 'Tuesday'), (14L, 'Mail Opened', 'Wednesday'), (6L, 'Mail Not Opened', 'Wednesday'), (1L, 'Mail Not Opened', 'Thursday'), (19L, 'Mail Opened', 'Thursday'), (28L, 'Mail Opened', 'Friday'), (1L, 'Mail Opened', 'Friday')]
d = {'Mail Opened': defaultdict(list), 'Mail Not Opened': defaultdict(list)}
for num,mail,day in lst:
d[mail][day].append(num)
这将在“Mail Opend”和“Mail Not Opened”之间划分您的输出。
但似乎我的问题很困惑,你希望输出除以DAYNAME。
在这种情况下,通过稍微调整,我们可以恢复字典的嵌套顺序:
from collections import defaultdict
lst = [(8, 'Mail Opened', 'Saturday'), (4, 'Mail Not Opened', 'Saturday'), (2, 'Mail Not Opened', 'Sunday'), (8, 'Mail Opened', 'Sunday'), (1, 'Mail Not Opened', 'Monday'), (1, 'Mail Not Opened', 'Monday'), (12, 'Mail Opened', 'Monday'), (10, 'Mail Opened', 'Tuesday'), (4, 'Mail Not Opened', 'Tuesday'), (14, 'Mail Opened', 'Wednesday'), (6, 'Mail Not Opened', 'Wednesday'), (1, 'Mail Not Opened', 'Thursday'), (19, 'Mail Opened', 'Thursday'), (28, 'Mail Opened', 'Friday'), (1, 'Mail Opened', 'Friday')]
days = defaultdict(lambda : {'Mail Opened': [], 'Mail Not Opened': []})
for num,mail,day in lst:
days[day][mail].append(num)
这将产生这种输出:
for k,v in days.iteritems():
print k, v
"""
Monday {'Mail Not Opened': [1, 1], 'Mail Opened': [12]}
Tuesday {'Mail Not Opened': [4], 'Mail Opened': [10]}
Friday {'Mail Not Opened': [], 'Mail Opened': [28, 1]}
Wednesday {'Mail Not Opened': [6], 'Mail Opened': [14]}
Thursday {'Mail Not Opened': [1], 'Mail Opened': [19]}
Sunday {'Mail Not Opened': [2], 'Mail Opened': [8]}
Saturday {'Mail Not Opened': [4], 'Mail Opened': [8]}
"""
这种方法将以完全相同的方式处理每个案例,因此如果您可以重构代码,我真的建议这个。
记下您的评论我找到了一个您要为('Friday', 'Mail Opened', ..)
提供两种不同输出的地方,例如:
[('Friday', 1L, 0), ('Friday', 28L, 0)]
而不是将它们链接到一起。这种特殊情况对你有意义吗?这是一个要求吗?如果答案是肯定的,请更新您的问题。
你还说你不会期望超过两个等于DAYNAME,但在你的例子中有3个Monday
,其中两个看起来相似,所以也许是一个错字(如果是,请更新你的问题) 。
但如果这是一个错字,你确定双星期五入口不是拼写错误吗?
无论如何,删除“额外”Monday
,并假设你真的需要这种输出(可能是出于兼容性API原因),你能做到:
lst = [(8, 'Mail Opened', 'Saturday'), (4, 'Mail Not Opened', 'Saturday'), (2, 'Mail Not Opened', 'Sunday'), (8, 'Mail Opened', 'Sunday'), (1, 'Mail Not Opened', 'Monday'), (12, 'Mail Opened', 'Monday'), (10, 'Mail Opened', 'Tuesday'), (4, 'Mail Not Opened', 'Tuesday'), (14, 'Mail Opened', 'Wednesday'), (6, 'Mail Not Opened', 'Wednesday'), (1, 'Mail Not Opened', 'Thursday'), (19, 'Mail Opened', 'Thursday'), (28, 'Mail Opened', 'Friday'), (1, 'Mail Opened', 'Friday')]
pos = {'Mail Opened': 1, 'Mail Not Opened': 2}
results = []
for num,mail,day in lst:
found = False
for x in results:
if day == x[0]:
found = True
if x[pos[mail]] == 0:
x[pos[mail]] = num
else: # this will handle your special case
new = [day, 0, 0]
new[pos[mail]] = num
results.append(new)
break
if not found:
new = [day, 0, 0]
new[pos[mail]] = num
results.append(new)
这将为您提供此输出:
for r in results:
print r
"""
['Saturday', 8, 4]
['Sunday', 8, 2]
['Monday', 12, 1]
['Tuesday', 10, 4]
['Wednesday', 14, 6]
['Thursday', 19, 1]
['Friday', 28, 0]
['Friday', 1, 0]
"""
您在评论中显示的错误(关于此答案和另一个答案)看起来像是在遮蔽内置list
。这意味着在代码中的某些时候,您可以执行以下操作:
list = # something
请勿这样做,请使用其他名称,例如lst
。
答案 1 :(得分:1)
尺寸硬编码,但你做了什么
import itertools
dat = [(8L, 'Mail Opened', 'Saturday'), (4L, 'Mail Not Opened', 'Saturday'),
(2L, 'Mail Not Opened', 'Sunday'), (8L, 'Mail Opened', 'Sunday'),
(1L, 'Mail Not Opened', 'Monday'), (1L, 'Mail Not Opened', 'Monday'),
(12L, 'Mail Opened', 'Monday'), (10L, 'Mail Opened', 'Tuesday'),
(4L, 'Mail Not Opened', 'Tuesday'), (14L, 'Mail Opened', 'Wednesday'),
(6L, 'Mail Not Opened', 'Wednesday'), (1L, 'Mail Not Opened', 'Thursday'),
(19L, 'Mail Opened', 'Thursday'), (28L, 'Mail Opened', 'Friday'), (1L, 'Mail Opened', 'Friday')]
solution = []
dat.sort(key=lambda t: t[2])
for day, grp in itertools.groupby(dat, key=lambda t: t[2]):
mo, mno = 0, 0
grp = list(grp)
if len(grp) == 1:
if grp[0][1] == 'Mail Opened':
solution.append((day, rec[0], 0))
elif grp[0][1] == 'Mail Not Opened':
solution.append((day, 0, rec[0]))
elif len(grp) == 2:
if grp[0][1] == grp[1][1]:
if grp[0][1] == 'Mail Opened':
solution.append((day, grp[0][0], 0))
solution.append((day, grp[1][0], 0))
elif grp[0][1] == 'Mail Not Opened':
solution.append((day, 0, grp[0][0]))
solution.append((day, 0, grp[1][0]))
else:
if grp[0][1] == 'Mail Opened':
solution.append((day, grp[0][0], grp[1][0]))
elif grp[1][0] == 'Mail Not Opened':
solution.append((day, grp[1][0], grp[0][0]))
print(solution)
"""
Solution:
[('Friday', 28L, 0), ('Friday', 1L, 0), ('Saturday', 8L, 4L),
('Tuesday', 10L, 4L), ('Wednesday', 14L, 6L)]
"""
答案 2 :(得分:0)
以下是使用单个defaultdict并在处理后将结果转换为所需表单的解决方案。
from collections import defaultdict
def convert(source):
days = defaultdict(lambda: [0, 0])
for item in source:
opened = 1
if item[1] == 'Mail Opened':
opened = 0
days[item[2]][opened] = item[0]
return days.iteritems()
source = [
(8L, 'Mail Opened', 'Saturday'),
(4L, 'Mail Not Opened', 'Saturday'),
(2L, 'Mail Not Opened', 'Sunday'),
(8L, 'Mail Opened', 'Sunday'),
(1L, 'Mail Not Opened', 'Monday'),
(1L, 'Mail Not Opened', 'Monday'),
(12L, 'Mail Opened', 'Monday'),
(10L, 'Mail Opened', 'Tuesday'),
(4L, 'Mail Not Opened', 'Tuesday'),
(14L, 'Mail Opened', 'Wednesday'),
(6L, 'Mail Not Opened', 'Wednesday'),
(1L, 'Mail Not Opened', 'Thursday'),
(19L, 'Mail Opened', 'Thursday'),
(28L, 'Mail Opened', 'Friday'),
(1L, 'Mail Opened', 'Friday')]
print list(convert(source))
结果:
[('Monday', [12L, 1L]),
('Tuesday', [10L, 4L]),
('Friday', [1L, 0]),
('Wednesday', [14L, 6L]),
('Thursday', [19L, 1L]),
('Sunday', [8L, 2L]),
('Saturday', [8L, 4L])]