循环迭代元组

3
我是一名Python初学者(20年后重新开始编程...)。
我正在编写一个小脚本,以便学习不规则英语动词。我创建了一个类似于以下内容的字典(它是法语):
verbes = {
"abide":["abode","abode","respecter / se conformer à"],
"arise":["arisen","arisen","survenir"],
}

如果我想遍历动词,可以采用以下方式:

例如:

for verb, (pret, past, trad) in verbes.items():
    print "Le verbe %s se conjugue au prétérit par %s, au participe passé par %s et se traduit par %s" % (verb, pret, past, trad)

好的,那很有效。然后我发现我可以导入random来从我的字典中随机选择一个键和值。

rand = random.choice(verbes.items())

如果我打印rand,我会得到一个键和值, 但是如果我再次迭代,就会出现回溯:

Traceback (most recent call last):
File ".\exverbe1.py", line 209, in <module>
    for verb, (pret, past, trad) in rand.items(): AttributeError: 'tuple' object has no attribute 'items'

我还没有学习过"元组"这一课,但尝试将其转换为列表、字典等都没有成功。我在stackoverflow上查看了"for循环元组"的相关内容,但没有找到解决方法。所以,经过三个小时的尝试后,现在我请求帮助......谢谢。


1
random.choice(verbes.items()) 会给你一个元组 (key, value)而不是一个字典。正如错误信息所述,元组没有 items 属性。 - jonrsharpe
你可以直接或间接地进行赋值:verb, (pret, past, trad) = random.choice(verbes.items()) or some_var_which_holds_keyval_tuple - Shashank
.items 返回一个元组列表,其中包含键/值对,random.choice 从这些元组中选择一个,因此您得到的是一个具有两个元素的元组而不是字典。 - Padraic Cunningham
你的期望输出是什么? - Shashank
我想随机打印动词、过去式、翻译,用户需要写下相应的过去式、动词过去式(如果出现“翻译”),或者过去式、动词翻译(如果出现“动词”)等。 - rEkOM
2个回答

2

random.choice(verbes.items()) 会从 verbes.items() 中随机选择一个元组。因此,rand 包含一个项目 - rand[0] 保存键,rand[1] 保存值。

如果你想要遍历值列表中的项目:

for val in rand[1]:
  print val

为了将rand元组解包为其组成部分:
verb, (pret, past, trad)

verb 现在包含关键字,而 pretpasttrad 分别是与关键字对应的列表中的每个元素。


1

rand 是从 verbes 中选出的一个项目,因此不需要再次调用 items:

rand = random.choice(verbes.items())
verb, (pret, past, trad) = rand

dict.items() 返回一个字典中的“项”列表,每个项都是形如 (key, value) 的元组。random.choice 返回其中的一个元组。我看到你正在尝试循环遍历 rand,也许你想要多个随机项?如果是这样,可以尝试以下操作:

for i in range(N):
     verb, (pret, past, trad) = random.choice(verbes.items())
     # Do more stuff

更新

在Python中,他们将类似 a, b = iterable 的赋值称为解包。您可以在右侧使用许多不同类型,例如:

# A tuple
a, b = ("A", "B")
# A list
a, b = ["A", "B"]
# A string
a, b = "AB"

在简单情况下,变量的数量需要与可迭代对象中的项目数量相同,否则Python会引发错误。您可以嵌套解包,如下所示:
 a, (b, c, d) = ("A", "BCD")
 # is the same as
 a, temp = ("A", "BCD")
 (b, c, d) = temp

()外面的括号是可选的,因此a, b = item(a, b) = item相同。

Python 3引入了更高级的解包类型,我从未使用过,但您可以在这里阅读有关它们的内容。


好的,谢谢,这很有效。但我不理解这一部分verb, (pret, past, trad) = rand,你是如何在一个变量中赋值所有这些内容的? - rEkOM
1
@rEkOM 我已经添加了Python解包规则的基本说明。 - Bi Rico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接