最近,我在回答一个问题。代码按预期工作。但我想看看我是否能实现我很少使用的dict理解。首先,让我解释一下problem。
OP有一个类似于M1 = [['a', 14], ['a',7], ['a',16],['b',3],['b',15],['c',22],['c',1],['c',5]]的示例列表。他们想要一个类似这样的输出。[['a',14,7,16],['b',3,15],['c',22,1,5]]。很有道理,所以我想出了一个答案。
原始代码
x = [['a', 14,15], ['a',7], ['a',16],['b',3],['b',15],['c',22],['c',1],['c',5]]
dictX = {}
for lsts in x:
if lsts[0] in dictX.keys():dictX[lsts[0]].extend(lsts[1:])
else:dictX[lsts[0]] = lsts[1:] 输出
{'a': [14, 15, 7, 16], 'b': [3, 15], 'c': [22, 1, 5]}go
x = [['a', 14,15], ['a',7], ['a',16],['b',3],['b',15],['c',22],['c',1],['c',5]]
dictX = {}
dictX ={(dictX[lsts[0]].extend(lsts[1:]) if lsts[0] in dictX.keys() else dictX[lsts[0]]): lsts[1:] for lsts in x}误差
"/Users/aspera/Documents/Python/Py_Programs/data/timeComplexity/test.py",跟踪(最近一次调用):dictX ={(dictX[lsts].extend( lsts1:),如果lsts在dictX.keys() dictX dictX[lsts]中):lsts1: lsts在x} "/Users/aspera/Documents/Python/Py_Programs/data/timeComplexity/test.py",第3行中in dictX ={(dictX[lsts].extend( lsts1:)如果lst在dictX.keys() lsts1 dictX[lsts]中):lsts1: for lst in x} KeyError:'a‘
在很多方面,我的尝试似乎都是错误的。我用这个作为reference (公认答案的顶部评论)
{(a if condition else b): value for key, value in dict.items()}有什么办法可以让我把这个转变成不理解。我想要一个类似于我提供的引用和我在原始代码中使用的逻辑的例子。
发布于 2021-05-09 01:52:36
通常,在理解过程中,您将无法引用字典本身,因为在理解完成之前,名称不会分配给最终的字典,因此您将不得不预先定义字典*并使用现有字典的变异方法。
由于您正在迭代输入列表,因此每当遇到键时,都需要用新值更新现有的字典。由于无法在字典理解中使用赋值,所以需要使用dict.update()方法(或__setitem__或setdefault)。该方法总是返回None,因此您可以利用它在字典理解中的许多不同地方实现预期的副作用。
特别是,将执行任何筛选条件子句,因此可以使用该子句。或者,expr or value将计算表达式,该表达式将始终返回None,因为这是falsey,所以整个表达式的计算结果为value,因此您可以将该表达式放在键或值中。这为我们提供了以下可能性:
在过滤器子句中有副作用:
d = {}
d = {k: d[k] for k, *vals in x if d.update({k: d.get(k, []) + vals}) is None}在expr or key表达式中产生副作用:
d = {}
d = {d.update({k: d.get(k, []) + vals}) or k: d[k] for k, *vals in x}在expr or value表达式中产生副作用:
d = {}
d = {k: d.update({k: d.get(k, []) + vals}) or d[k] for k, *vals in x}*使用赋值表达式(Python 3.8+),您可以在理解本身内预先定义字典,其中包括:
d = {k: d.update({k: d.get(k, []) + vals}) or d[k] for i, (k, *vals) in enumerate(x) if i or not (d := {})}这使用enumerate()来检测第一次迭代时的情况,在这种情况下,赋值表达式可以构造用于理解的其余部分的字典。在第一次迭代之后,赋值表达式不再被计算,因此d在评估过程中不会被重新分配。
注意:很明显,这个答案中显示的所有方法都很糟糕。理解中的副作用是不必要的、意想不到的、令人困惑的,一句话就是愚蠢。不要使用此代码。但是看看什么是可能的是很有趣的!
发布于 2021-05-05 02:38:05
由于嵌套循环而不是更快,但它是可行的。使用清单理解内部的理解。
seq = [['a', 14,15], ['a',7], ['a',16],['b',3],['b',15],['c',22],['c',1],['c',5]]
res = {i[0]:[k for j in seq if j[0] == i[0] for k in j[1:]] for i in seq}
print(res)输出
{'a': [14, 15, 7, 16], 'b': [3, 15], 'c': [22, 1, 5]}PS :我意识到这个问题更多的是与Is it possible to access current object while doing list/dict comprehension in Python?有关,如果有人觉得这是一个欺骗,做标记它,我不确定,所以我要离开它。
https://stackoverflow.com/questions/67394401
复制相似问题