以单行for循环为列表项分配

问题描述 投票:1回答:4

我想在单行for循环中对列表项进行赋值。

首先我有一个列表,其中每个列表项都是字典对象。然后,我在列表的每个项目上循环,并比较字典的'nodeid'字段是否为106.如果是,我将新字段添加到该字典。代码如下。

K= []
K.append({'nodeid': 100 ,'elemid': 200})
K.append({'nodeid': 106 ,'elemid': 206})
K.append({'nodeid': 107 ,'elemid': 206})
for item in K: 
   if item['nodeid']==106: 
     item['S']= [2 , 124, 123 , 3532, 35]

我想在一行中写出算法的循环部分,类似于

[item['S']=12343 for item in K if item['nodeid']==106]

但这种方法不起作用。如何在一行中编写此循环?

谢谢

python list for-loop variable-assignment
4个回答
1
投票

正如我在评论中所说,为这项任务写一个单行程并不是一种方法,因为你失去的可读性是巨大的。

但是,如果出于纯粹的好奇心,你可以这样做:

K = [x if x['nodeid'] != 106 else dict(x, **{'S': [2 , 124, 123 , 3532, 35]}) for x in K]

这里的魔法发生在dict(x, **{'S': [2 , 124, 123 , 3532, 35]})上,它基本上将两个diction加在一起并返回它们的结果。


1
投票

Python 3.5+

K = [{**d, 'S': [2 , 124, 123 , 3532, 35]} if d['nodeid'] == 106 else d for d in K]

1
投票

如果你愿意,你当然可以这样做,就像这样:

K = []
K.append({'nodeid': 100 ,'elemid': 200})
K.append({'nodeid': 106 ,'elemid': 206})
K.append({'nodeid': 107 ,'elemid': 206})

K = [item if item['nodeid'] != 106 else dict(S=[2 , 124, 123 , 3532, 35], **item) for item in K]

**是Python的“爆炸”或解包操作符的版本,在字典上使用,详细描述了over here


但是,考虑到nodeid,看起来您的数据已经在字典中,所以为什么不重新构建它呢?

K = {}
K[100] = {'elemid': 200}
K[106] = {'elemid': 206}
K[107] = {'elemid': 206}

K[106]['S'] = [2 , 124, 123 , 3532, 35]

这是使用散列/表数据结构的好处:快速方便(更不用说,可读)索引。每个元素的位置都是已知的,除非您有二级键标准,否则不需要对包含的元素进行任何类型的迭代。

此外,通过使用字典,您可以避免重建整个列表的成本,这通过在给定的第一个示例中使用列表推导来实现。但是请注意,如果您使用的是开头的for循环,则不会出现此问题,因为只有在找到后才会更改元素,如果在完成操作后break,循环将完成而不会产生任何额外费用。


0
投票

如果你有很多项目,写一个单行意味着重建整个列表,如果你有稀疏的值要改变,这不是很有效。

在单行中(适用于所有版本的python> = 2.7):

K = [d if d['nodeid']!=106 else {k:v for k,v in list(d.items())+[('S',[2 , 124, 123 , 3532, 35])]} for d in K]

如果id不匹配,发出子列表,否则用子列表+额外元素构建一个字典(不使用所有python版本都没有的花哨的“字典添加”)

© www.soinside.com 2019 - 2024. All rights reserved.