使用列表中列表的 for 循环更新字典中的值
Updating Values in Dictionary with for Loop of a List within a List
我知道此 post 底部代码的 logic/syntax 已关闭,但我很难弄清楚如何编写此代码以获得所需的结果。第一部分创建此字典:
sco = {'human + big': 0, 'big + loud': 0, 'big + human': 0, 'human + loud': 0, 'loud + big': 0, 'loud + human': 0}
然后,我的意图是为 x 循环遍历字典 "cnt" 中的每个项目一次,然后在每次该项目具有与 (cnt[x) 相同的值时为 x 第二次循环字典][1]) 但是一个不同的键 (cnt[x][0]),创建一个与字典中找到的格式“%s + %s”相匹配的字符串 "sco." 然后它应该在中找到键sco 匹配分配给变量 dnt 的键并将 sco 中该键的值增加 1.
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = cnt[x][0]
who = cnt[x][1]
for x in cnt:
if cnt[x][0] != upd and cnt[x][1] == who:
cpg = cnt[x][0]
dnt = '%s + %s' % (upd, cpg)
for i in sco:
if sco[i][0] == dnt:
sco[i][1] += sco[i][1]
print sco
目前,打印 sco 不会导致任何值发生变化。代码的预期结果是:
{'human + big': 1, 'big + loud': 0, 'big + human': 1, 'human + loud': 2, 'loud + big': 0, 'loud + human': 2}
非常感谢任何帮助!
修改后的代码是这样的:
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = cnt[0]
who = cnt[1]
for x in cnt:
if cnt[0] != upd and cnt[1] == who:
cpg = cnt[0]
dnt = '%s + %s' % (upd, cpg)
sco[dnt] += 1
print sco
以下代码实现了我的预期。感谢@dermen & @abarnert:
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = x[0]
who = x[1]
for x in cnt:
if x[0] != upd and x[1] == who:
cpg = x[0]
dnt = '%s + %s' % (upd, cpg)
sco[dnt] += 1
print sco
实际问题是,您不是将值加 1,而是将它们加倍:
sco[i][1] += sco[i][1]
而且不管你把0加多少次0,它还是0。
要加1,只需使用+= 1
。
但是您还有另一个问题,至少在您发布的代码中。每个 sco[i]
值只是一个数字,而不是两个事物的列表,其中第二个是一个数字。所以你真正想要的是:
sco[i] += 1
同样,键不是 sco[i][0]
,它们只是 i
。
你遇到了第三个问题。这个实际上并没有破坏你的代码,它只是让它变得更复杂、更难理解、更慢……但这仍然值得修复。
字典的全部意义在于您不必重复查找关键字,您只需直接查找关键字即可。所以,而不是这个:
for i in sco:
if i == dnt:
sco[i] += 1
…就这样做:
sco[dnt] += 1
同时更简单、更难出错、更高效。
我不能保证您的代码中没有其他错误,但是除了其他任何错误之外,您肯定需要修复这三个错误,而且我很确定第一个错误就是发生的错误导致您询问的具体问题。
除了@abarnert 回复的内容,字典的行为如下:
>>> D1 = { 'thing1': [1,2,3 ], 'thing2': ( 1, 2,3), 'thing3':'123' }
>>> D1['thing1']
#[1, 2, 3]
>>> D1['thing2']
#(1, 2, 3)
>>> D1['thing3']
#'123'
>>> thing4 = 1
>>> D2 = { thing4:D1 }
>>> D2[thing4]
#{'thing1': [1, 2, 3], 'thing2': (1, 2, 3), 'thing3': '123'}
如果要遍历字典的键,请使用
>>> D1.keys()
#['thing2', 'thing3', 'thing1']
>>> D2.keys()
#[1]
最后,我建议为您的 "key" 制作一个模板,这样
>>> template = "{0} + {1}"
然后你可以替换行
sco["{0} + {1}".format(a,b)] = 0
和
sco[template.format(a,b)] = 0
类似地
dnt = '%s + %s' % (upd, cpg)
和
dnt = template.format(upd, cpg)
-我认为这是更安全的做法。阅读更多关于字典的内容 here, see section 5.5.
使用 defaultdict 并按元组中的项目分组的解决方案:
import itertools
from collections import defaultdict
sho = ('human', 'loud', 'big')
sco = {}
for a, b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a, b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
groups = defaultdict(list)
for obj in cnt:
groups[obj[1]].append(obj[0])
final_list = []
# create list of pairs a + b
final_list.extend(map(lambda x: " + ".join(x), groups.values()))
for key in groups.keys():
groups[key].reverse()
# create list of pairs b + a
final_list.extend(map(lambda x: " + ".join(x), groups.values()))
for val in final_list:
if val in sco:
sco[val] += 1
print(sco)
这里我们:
- 将
cnt
元组按人分组到字典中
- 从上一步创建值对列表
- 创建反向对(根据OP的预期结果)
- 计数
sco
中存在的对
结果:
{'human + loud': 2, 'loud + human': 2, 'loud + big': 0, 'human + big': 1, 'big + loud': 0, 'big + human': 1}
我知道此 post 底部代码的 logic/syntax 已关闭,但我很难弄清楚如何编写此代码以获得所需的结果。第一部分创建此字典:
sco = {'human + big': 0, 'big + loud': 0, 'big + human': 0, 'human + loud': 0, 'loud + big': 0, 'loud + human': 0}
然后,我的意图是为 x 循环遍历字典 "cnt" 中的每个项目一次,然后在每次该项目具有与 (cnt[x) 相同的值时为 x 第二次循环字典][1]) 但是一个不同的键 (cnt[x][0]),创建一个与字典中找到的格式“%s + %s”相匹配的字符串 "sco." 然后它应该在中找到键sco 匹配分配给变量 dnt 的键并将 sco 中该键的值增加 1.
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = cnt[x][0]
who = cnt[x][1]
for x in cnt:
if cnt[x][0] != upd and cnt[x][1] == who:
cpg = cnt[x][0]
dnt = '%s + %s' % (upd, cpg)
for i in sco:
if sco[i][0] == dnt:
sco[i][1] += sco[i][1]
print sco
目前,打印 sco 不会导致任何值发生变化。代码的预期结果是:
{'human + big': 1, 'big + loud': 0, 'big + human': 1, 'human + loud': 2, 'loud + big': 0, 'loud + human': 2}
非常感谢任何帮助!
修改后的代码是这样的:
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = cnt[0]
who = cnt[1]
for x in cnt:
if cnt[0] != upd and cnt[1] == who:
cpg = cnt[0]
dnt = '%s + %s' % (upd, cpg)
sco[dnt] += 1
print sco
以下代码实现了我的预期。感谢@dermen & @abarnert:
# -*- coding: utf-8 -*-
import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a,b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
upd = x[0]
who = x[1]
for x in cnt:
if x[0] != upd and x[1] == who:
cpg = x[0]
dnt = '%s + %s' % (upd, cpg)
sco[dnt] += 1
print sco
实际问题是,您不是将值加 1,而是将它们加倍:
sco[i][1] += sco[i][1]
而且不管你把0加多少次0,它还是0。
要加1,只需使用+= 1
。
但是您还有另一个问题,至少在您发布的代码中。每个 sco[i]
值只是一个数字,而不是两个事物的列表,其中第二个是一个数字。所以你真正想要的是:
sco[i] += 1
同样,键不是 sco[i][0]
,它们只是 i
。
你遇到了第三个问题。这个实际上并没有破坏你的代码,它只是让它变得更复杂、更难理解、更慢……但这仍然值得修复。
字典的全部意义在于您不必重复查找关键字,您只需直接查找关键字即可。所以,而不是这个:
for i in sco:
if i == dnt:
sco[i] += 1
…就这样做:
sco[dnt] += 1
同时更简单、更难出错、更高效。
我不能保证您的代码中没有其他错误,但是除了其他任何错误之外,您肯定需要修复这三个错误,而且我很确定第一个错误就是发生的错误导致您询问的具体问题。
除了@abarnert 回复的内容,字典的行为如下:
>>> D1 = { 'thing1': [1,2,3 ], 'thing2': ( 1, 2,3), 'thing3':'123' }
>>> D1['thing1']
#[1, 2, 3]
>>> D1['thing2']
#(1, 2, 3)
>>> D1['thing3']
#'123'
>>> thing4 = 1
>>> D2 = { thing4:D1 }
>>> D2[thing4]
#{'thing1': [1, 2, 3], 'thing2': (1, 2, 3), 'thing3': '123'}
如果要遍历字典的键,请使用
>>> D1.keys()
#['thing2', 'thing3', 'thing1']
>>> D2.keys()
#[1]
最后,我建议为您的 "key" 制作一个模板,这样
>>> template = "{0} + {1}"
然后你可以替换行
sco["{0} + {1}".format(a,b)] = 0
和
sco[template.format(a,b)] = 0
类似地
dnt = '%s + %s' % (upd, cpg)
和
dnt = template.format(upd, cpg)
-我认为这是更安全的做法。阅读更多关于字典的内容 here, see section 5.5.
使用 defaultdict 并按元组中的项目分组的解决方案:
import itertools
from collections import defaultdict
sho = ('human', 'loud', 'big')
sco = {}
for a, b in itertools.permutations(sho, 2):
sco["{0} + {1}".format(a, b)] = 0
cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
groups = defaultdict(list)
for obj in cnt:
groups[obj[1]].append(obj[0])
final_list = []
# create list of pairs a + b
final_list.extend(map(lambda x: " + ".join(x), groups.values()))
for key in groups.keys():
groups[key].reverse()
# create list of pairs b + a
final_list.extend(map(lambda x: " + ".join(x), groups.values()))
for val in final_list:
if val in sco:
sco[val] += 1
print(sco)
这里我们:
- 将
cnt
元组按人分组到字典中 - 从上一步创建值对列表
- 创建反向对(根据OP的预期结果)
- 计数
sco
中存在的对
结果:
{'human + loud': 2, 'loud + human': 2, 'loud + big': 0, 'human + big': 1, 'big + loud': 0, 'big + human': 1}