使用Lis中列表的for循环更新字典中的值

2024-05-16 09:41:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道这篇文章底部的代码的逻辑/语法是错误的,但是我很难弄清楚如何写这个来得到想要的结果。第一节创建此词典:

sco = {'human + big': 0, 'big + loud': 0, 'big + human': 0, 'human + loud': 0, 'loud + big': 0, 'loud + human': 0}

然后,我的意图是对字典“cnt”中的每个项循环一次x,然后对字典循环第二次x,每次该项的值与(cnt[x][1])相同,但键不同(cnt[x][0]),创建一个字符串,该字符串将匹配字典“sco”中的格式“%s+%s”。然后,它将在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

Tags: inforitertoolshumanwhobigcntloud
3条回答

使用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元组分组到dict中
  • 从上一步创建值对列表
  • 创建反向对(根据OP的预期结果)
  • sco中存在的对进行计数

结果:

 {'human + loud': 2, 'loud + human': 2, 'loud + big': 0, 'human + big': 1, 'big + loud': 0, 'big + human': 1}

实际问题是,不是将值加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]

最后,我建议为你的“钥匙”制作一个模板,这样

>>> 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.

相关问题 更多 >