如果元组中的第一个值 = 1,则从字典值列表中删除元组
Remove tuples from dictionary value list if first value in tuple = 1
首先,我有一个字典 d1,如下所示:
d1 = { 'w' : ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c'],
'x' : ['d', 'd', 'd', 'e', 'e'],
'y' : ['f', 'f', 'g'],
'z' : ['h', 'i']
}
然后我遍历该字典并创建一个新字典,其中每个值都是一个包含两个元素的列表:一个整数和一个列表。整数是 d1 中该值中的字符串数。该列表包含元组,每个元组包含来自 d1 的字符串(在元组的位置 1)和该字符串在 d1 中出现的次数(在元组的位置 0):
d2 = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')],
'x' : [5, [(3, 'd'), (2, 'e')],
'y' : [3, [(2, 'f'), (1, 'g')],
'z' : [2, [(1, 'h'), (1, 'i')]
}
我想删除任何只出现一次的字符串('g'、'h'和'i'),所以最后我想要:
dFinal = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')],
'x' : [5, [(3, 'd'), (2, 'e')],
'y' : [2, [(2, 'f')]
}
我读了一个我认为是字典理解的示例,如果值列表的长度小于 2,则删除整个字典项目:
d = {k:v for k,v in d.items() if len(v) > 1}
我正在尝试掌握 list/dictionary 理解,并希望使用类似的方法来实现我所描述的内容,并在此过程中学到一些东西。
一开始我试着写了一个以d2为参数的函数,但是我不知道如何引用每个元组的位置0。
然后认为使用没有元组的 d1 生成 dFinal 可能比尝试更改 d2 更容易。
如果您能描述一种从 d1 and/or d2 生成 dFinal 的干净方法,并解释思考过程,我将不胜感激。两者都会真正帮助我理解如何通过理解精确地操作字典列表。
谢谢!
好吧,您可以使用 Counter
对象。老实说,我会使用循环,因为它可能更有效率。
In [1]: from collections import Counter
编辑:这是我实际上会如何做的,没有理解:
In [17]: for k,v in d1.items():
...: counts = Counter(v)
...: counts = [t for t in counts.items() if t[1] > 1]
...: if len(counts) > 0:
...: dfinal[k] = [sum(c[1] for c in counts), counts]
...:
In [18]: dfinal
Out[18]:
{'w': [10, [('b', 3), ('a', 5), ('c', 2)]],
'x': [5, [('d', 3), ('e', 2)]],
'y': [2, [('f', 2)]]}
我觉得不是很好的风格,但是你可以这样做:
dFinal = {k: [sum([i for i, c in v[1] if i != 1]),
[(i, c) for i, c in v[1] if i != 1]]
for k, v in d2.items()
if [(i, c) for i, c in v[1] if i != 1]}
编辑:现在更新计数。同样,如果理解看起来像这样,是时候重构了。
这个
from collections import Counter
d2 = {k: [len(v), sorted(Counter(v).items())] for k, v in d1.items()}
dFinal = {k: [v1, [(y, x) for x, y in v2 if y > 1]] for k, (v1, v2) in d2.items()}
我的 d2
和 dFinal
与您的略有不同。这是我的 d2
{'w': [10, [('a', 5), ('b', 3), ('c', 2)]],
'x': [5, [('d', 3), ('e', 2)]],
'y': [3, [('f', 2), ('g', 1)]],
'z': [2, [('h', 1), ('i', 1)]]}
这是我的dFinal
{'w': [10, [(5, 'a'), (3, 'b'), (2, 'c')]],
'x': [5, [(3, 'd'), (2, 'e')]],
'y': [3, [(2, 'f')]],
'z': [2, []]}
但您自己可以轻松解决这个问题。
顺便说一句:我会使用函数使字典和列表理解看起来更容易。现在它是不可读的。
另一种选择:速度较慢但更容易理解:
def has_dupe(lst):
return any([x[0] > 1 for x in lst[1]])
def reduce_list(lst):
result = [(x, y) for (x, y) in lst[1] if x > 1]
return [sum([x for (x, y) in result]), result]
d = {key: reduce_list(value) for key, value in d2.items() if has_dupe(value)}
首先,我有一个字典 d1,如下所示:
d1 = { 'w' : ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c'],
'x' : ['d', 'd', 'd', 'e', 'e'],
'y' : ['f', 'f', 'g'],
'z' : ['h', 'i']
}
然后我遍历该字典并创建一个新字典,其中每个值都是一个包含两个元素的列表:一个整数和一个列表。整数是 d1 中该值中的字符串数。该列表包含元组,每个元组包含来自 d1 的字符串(在元组的位置 1)和该字符串在 d1 中出现的次数(在元组的位置 0):
d2 = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')],
'x' : [5, [(3, 'd'), (2, 'e')],
'y' : [3, [(2, 'f'), (1, 'g')],
'z' : [2, [(1, 'h'), (1, 'i')]
}
我想删除任何只出现一次的字符串('g'、'h'和'i'),所以最后我想要:
dFinal = { 'w' : [10, [(5, 'a'), (3, 'b'), (2, 'c')],
'x' : [5, [(3, 'd'), (2, 'e')],
'y' : [2, [(2, 'f')]
}
我读了一个我认为是字典理解的示例,如果值列表的长度小于 2,则删除整个字典项目:
d = {k:v for k,v in d.items() if len(v) > 1}
我正在尝试掌握 list/dictionary 理解,并希望使用类似的方法来实现我所描述的内容,并在此过程中学到一些东西。
一开始我试着写了一个以d2为参数的函数,但是我不知道如何引用每个元组的位置0。
然后认为使用没有元组的 d1 生成 dFinal 可能比尝试更改 d2 更容易。
如果您能描述一种从 d1 and/or d2 生成 dFinal 的干净方法,并解释思考过程,我将不胜感激。两者都会真正帮助我理解如何通过理解精确地操作字典列表。
谢谢!
好吧,您可以使用 Counter
对象。老实说,我会使用循环,因为它可能更有效率。
In [1]: from collections import Counter
编辑:这是我实际上会如何做的,没有理解:
In [17]: for k,v in d1.items():
...: counts = Counter(v)
...: counts = [t for t in counts.items() if t[1] > 1]
...: if len(counts) > 0:
...: dfinal[k] = [sum(c[1] for c in counts), counts]
...:
In [18]: dfinal
Out[18]:
{'w': [10, [('b', 3), ('a', 5), ('c', 2)]],
'x': [5, [('d', 3), ('e', 2)]],
'y': [2, [('f', 2)]]}
我觉得不是很好的风格,但是你可以这样做:
dFinal = {k: [sum([i for i, c in v[1] if i != 1]),
[(i, c) for i, c in v[1] if i != 1]]
for k, v in d2.items()
if [(i, c) for i, c in v[1] if i != 1]}
编辑:现在更新计数。同样,如果理解看起来像这样,是时候重构了。
这个
from collections import Counter
d2 = {k: [len(v), sorted(Counter(v).items())] for k, v in d1.items()}
dFinal = {k: [v1, [(y, x) for x, y in v2 if y > 1]] for k, (v1, v2) in d2.items()}
我的 d2
和 dFinal
与您的略有不同。这是我的 d2
{'w': [10, [('a', 5), ('b', 3), ('c', 2)]],
'x': [5, [('d', 3), ('e', 2)]],
'y': [3, [('f', 2), ('g', 1)]],
'z': [2, [('h', 1), ('i', 1)]]}
这是我的dFinal
{'w': [10, [(5, 'a'), (3, 'b'), (2, 'c')]],
'x': [5, [(3, 'd'), (2, 'e')]],
'y': [3, [(2, 'f')]],
'z': [2, []]}
但您自己可以轻松解决这个问题。
顺便说一句:我会使用函数使字典和列表理解看起来更容易。现在它是不可读的。
另一种选择:速度较慢但更容易理解:
def has_dupe(lst):
return any([x[0] > 1 for x in lst[1]])
def reduce_list(lst):
result = [(x, y) for (x, y) in lst[1] if x > 1]
return [sum([x for (x, y) in result]), result]
d = {key: reduce_list(value) for key, value in d2.items() if has_dupe(value)}