遍历元组列表并仅解包第一个元素

3
假设有以下列表:foo = [(1, 2, 3, 4), (5, 6, 7, 8)],是否可以迭代该列表并仅解压内部元组的前两个元素?通常的方法是:{a: b for a, b, _, _ in foo},但如果foo被修改(程序更改)并且元组现在包含5个元素而不是4个元素,则会出错(需要相应地修改列表推导式)。我喜欢对元素进行命名,而不是调用{f[0]: f[1] for f in foo},因此理想情况下,应该有一种“吸收所有未解压变量”的方法,这样可以调用 {a: b for a, b, absorb_rest in foo}。 如果可能的话,无论元组中包含多少元素(只要至少有2个元素),都没有关系。

你希望你的结果看起来像什么? - Ma0
在上面的例子中:{1: 2, 5: 6},但那只是一个例子。我想从元组中提取前两个元素,因此例如,如果我要查找[a + b for a, b, _, _ in foo],我期望得到[3, 11] - orange
4个回答

5

不,我对剩余的值不感兴趣(我只是被你的评论“否则它们将不必要地保留在内存中”所困惑)。我的理解是*_*c是等价的(都是变量),并且对变量的最后一次赋值(最后一次迭代)将在列表推导式之后可用。 - orange
1
@yatu 我不认为这是正确的。在这里,_ 是一种约定俗成的写法,我不相信它在任何情况下都不会分配内存。例如 a, _ = [1, 2]; print(_) 或者(虽然不太好的写法)a = [print(a, _) for a, _ in [[1, 2], [3, 4]]] - roganjosh
@roganjosh 我同意这一点。这就是我的困惑所在。_c都是等价的变量名称(_更常用,因为它是一个约定)。 - orange
1
下划线在这里的惯例之外还有其他用途,比如这个 - roganjosh
啊,刚学到了新东西:))会清理掉@roganjosh devesh的注释。 - yatu
显示剩余4条评论

5

您可以使用扩展可迭代对象拆包,提取元组的前两个元素并忽略其余的元素。请注意,这仅适用于python3

{a:b for a, b, *c in foo}                                                                                                                                                             

如其他人所建议的那样,*_ 更符合惯用语。 - Chris_Rands
哇,那是Python 3特定的吗? - orange
是的和不是。我需要尽快更新。Python 2.7有类似的解决方案吗? - orange
抱歉,你是正确的,pylint并不介意,我想知道为什么。我认为PyCharm会检测到这个问题。 - Chris_Rands
@Chris_Rands 使用 _ 变量会触发 mypy(Python 的严格类型检查 linter)的警告,因为每当它看到您重复使用 _ 时,它们的“类型不匹配”。所以我已经停止使用 _... - Mitch McMabers

3
试试这个:
dict_ = {a:b for a,b, *_ in foo}

输出

{1: 2, 5: 6}

如果程序将foo更改为[(1, 2, 3, 4,9,0), (5, 6, 7, 8, 11, 16)],则dict_仍然保持为:{1: 2, 5: 6}

0

使用lambda

foo = [(1, 2, 3, 4), (5, 6, 7, 8)]
output = list(map(lambda x:{x[0]:x[1]}, foo))
print(output)

输出

[{1: 2}, {5: 6}]

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