简体   繁体   English

如何重构我的for循环作为python字典理解?

[英]How to refactor my for loop as python dictionary comprehension?

I am using Python 3.6. 我使用的是Python 3.6。 I wrote following code, it's a for loop: 我写了下面的代码,它是一个for循环:

Edit : I made a mistake when I wrote var l down, so I re-type it here. 编辑 :当我写下var时我犯了一个错误,所以我在这里重新键入它。 Thanks for @Ender Look !! 感谢@Ender Look !!

l = [['a','1'], ['a','2'], ['a','3']]
d = {}
for i in l:
    d[i[0]] = d.get(i[0], '') + '\t' + i[1]
print (d)

So, the result is what I want: {'a': '\\t1\\t2\\t3'} 所以,结果就是我想要的: {'a':'\\ t1 \\ t2 \\ t3'}

Then I refactor above code as comprehension: 然后我重构上面的代码作为理解:

dict2 = {} dict2 = {i[0]: dict2.get(i[0], '') + '\\t' + i[1] for i in l} print(dict2)

I though they should return same output. 我虽然他们应该返回相同的输出。 But the dict2 is: 但是dict2是:

{'a': '\\t3'} {'a':'\\ t3'}

I want to know what's the matter with my dict comprehension? 我想知道我的词汇理解是什么问题? Thanks a lot! 非常感谢!

You don't necessarily need to use a comprehension here. 你不一定需要在这里使用理解。 You can make use of defaultdict from collections : 您可以使用集合中defaultdict

>>> from collections import defaultdict
>>> d = defaultdict(str)
>>> for li in l:
...  d[li[0]] += f'\t{li[1]}'
...
>>> d
defaultdict(<class 'str'>, {'a': '\t1\t2'})

Your dictionary comprehension doesn't work because it's use .get on itself. 你的词典理解不起作用,因为它本身就是使用.get

dict2 = {i[0]: dict2.get(i[0], '') + '\t' + i[1] for i in l}

Until the end of the whole dictionary comprehension, this new dictionary isn't assigned to your actual dict2 variable. 直到整个词典理解结束,这个新词典没有分配给你的实际dict2变量。 So all the times your comprehension tries to retrieve the value from dict2.get(...) it always executes that function from the empty dictionary dict2 = {} . 所以,你的理解总是尝试从dict2.get(...)检索值,它总是从空字典dict2 = {}执行该函数。

Sadly, I don't know (and I don't think it exists) a way to use .get on a dictionary comprehension about itself, because the variable dict2 isn't updated on "real time" (it wait until the end the comprehension). 可悲的是,我不知道(我认为它不存在)一种方法来使用.get对字典理解它自己,因为变量dict2没有在“实时”更新(它等到结束时理解)。 Or at least that I have understood, my humble knowledge isn't perfect. 或者至少我明白了,我的谦虚知识并不完美。

Yes, you can do it as a single dict comprehension. 是的,你可以把它作为单一的词典理解。

{k: v
 for d in [{}]
 for k, v in [d.__setitem__(k, d.get(k, '') + '\t' + v) or d 
              for k, v in [['a','1'], ['a','2'], ['a','3']]][-1].items()}

You shouldn't. 你不应该。

Note how we had to create a reference to an inner dict d anyway, since your algorithm has to look things up in the dict as it's being constructed . 注意我们如何创建对内部字典d的引用,因为你的算法必须在dict中查找正在构建的内容 What is the outer comprehension even for ? 甚至对于外在理解是什么? And we're throwing away all but the last element of the inner list comp. 而且我们除了内部列表comp的最后一个元素之外都丢掉了。

It's much clearer to use a normal for loop like this, 使用这样的普通for循环要清楚得多,

d = {}
for k, v in [['a','1'], ['a','2'], ['a','3']]:
    d[k] = d.get(k, '') + '\t' + v

Use the right tool for the job. 使用正确的工具完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM