简体   繁体   English

在Python字典中遍历值列表

[英]iterating over values list in Python dictionary

Hi I am looking to iterate over a Python dictionary where each key has a list of values, I am looking to either create a new list/dictionary where I have separated each value[x] or directly do stuff with the separated values. 嗨,我想遍历每个关键字都有值列表的Python字典,我想创建一个新的列表/字典来分隔每个值[x]或直接用分隔的值做事。

here's a simplified example of the dictionary I have: 这是我拥有的字典的简化示例:

all_parameters = {"first": ["1a","1b","1c"], "second": ["2a","2b","2c"], "third": ["3a","3b","3c"]}

I am looking to separate the values like this (either by creating a new dictionary or list or directly doing stuff with the separated values). 我正在寻找这样的值分开(通过创建一个新的字典或列表或直接用分开的值做事)。

grouped_parameters = [{"first": "1a", "second": "2a", "third": "3a"},
                      {"first": "1b", "second": "2b", "third": "3b"},
                      {"first": "1c", "second": "2c", "third": "3c"}]

I am insure how to iterate correctly over each key:value pair. 我确保如何正确迭代每个key:value对。

i = 0
for k, v in all_parameters.items():
    for item in v:
        # stuck here
    i+=1

Eventually the 'stuff' I am looking to do is convert each output (eg '{"first": "1a", "second": "2a", "third": "3a"}') into a string so that I can post each parameter group to a cell in a table, so ideally i'd prefer to do this dynamically instead of creating a new dictionary. 最终,我要执行的“工作”是将每个输出(例如,“ {{first”:“ 1a”,“ second”:“ 2a”,“ third”:“ 3a”}')转换为字符串,这样我可以将每个参数组发布到表中的单元格,因此理想情况下,我宁愿动态地执行此操作,而不是创建新的字典。

Any help would be greatly appreciated. 任何帮助将不胜感激。

Assuming all lists have the same length: 假设所有列表的长度相同:

>>> length = len(next(all_parameters.itervalues()))
>>> [{k:v[i] for k,v in all_parameters.iteritems()} for i in range(length)]
[{'second': '2a', 'third': '3a', 'first': '1a'}, {'second': '2b', 'third': '3b', 'first': '1b'}, {'second': '2c', 'third': '3c', 'first': '1c'}]

In Python 3, use len(next(iter(all_parameters.values()))) and items instead of iteritems . 在Python 3中,使用len(next(iter(all_parameters.values())))items而不是iteritems

(The iterator shenanigans are done because you don't need a list of all the dictionary values if you only want the length of an arbitrary value-list.) (完成迭代器的恶作剧是因为如果只需要任意值列表的长度,则不需要所有字典值的列表。)

The items in a plain dict aren't ordered *, so you need to be careful when converting a dict to a string if you want the fields to be in a certain order. 普通字典中的项目没有排序*,因此,如果要将字段转换为特定顺序,则在将字典转换为字符串时需要格外小心。

This code uses a tuple containing the key strings in the order we want them to be in in the output dict strings. 此代码使用一个元组,其中包含我们希望它们在输出dict字符串中出现的顺序的键字符串。

all_parameters = {
    "first": ["1a","1b","1c"], 
    "second": ["2a","2b","2c"], 
    "third": ["3a","3b","3c"],
}

# We want keys to be in this order
all_keys = ("first", "second", "third")

# Assumes all value lists are the same length.
for t in zip(*(all_parameters[k] for k in all_keys)):
    a = ['"{}": "{}"'.format(u, v) for u, v in zip(all_keys, t)]
    print('{' + ', '.join(a) + '}')

output 产量

{"first": "1a", "second": "2a", "third": "3a"}
{"first": "1b", "second": "2b", "third": "3b"}
{"first": "1c", "second": "2c", "third": "3c"}

How it works 这个怎么运作

We first use a generator expression (all_parameters[k] for k in all_keys) which yields the value lists from all_parameters in the order specified by all_keys . 我们首先使用生成器表达式(all_parameters[k] for k in all_keys) ,该表达式按all_keys指定的顺序从all_parameters中生成值列表。 We pass those lists as args to zip using the * "splat" operator. 我们使用* “ splat”运算符将这些列表作为args传递给zip So for your example data, it's equivalent to calling zip like this: 因此,对于您的示例数据,它相当于像这样调用zip

zip(["1a","1b","1c"], ["2a","2b","2c"], ["3a","3b","3c"])

zip effectively transposes the iterables you pass it, so the result of that call is an iterator that produces these tuples: zip有效地转换了传递给它的可迭代对象,因此该调用的结果是生成这些元组的迭代器:

('1a', '2a', '3a'), ('1b', '2b', '3b'), ('1c', '2c', '3c')

We then loop over those tuples one by one, with the for t in zip(...) , so on the first loop t gets the value ('1a', '2a', '3a') , then ('1b', '2b', '3b') , etc. 然后我们用for t in zip(...)for t in zip(...)逐个循环这些元组,因此在第一个循环中t获得值('1a', '2a', '3a') ,然后是('1b', '2b', '3b')等。

Next we have a list comprehension that zips the value strings up with the corresponding key string and formats them into a string with double-quotes around each key and value string. 接下来,我们有一个列表推导,它将值字符串和相应的键字符串压缩在一起,并将它们格式化为在每个键和值字符串周围用双引号引起来的字符串。 We then join those strings together with commas and spaces as separators (and add brace characters) to make our final dict strings. 然后,我们将这些字符串与逗号和空格作为分隔符连接在一起(并添加大括号字符)以构成最终的dict字符串。


* Actually in Python 3.6 plain dicts do retain insertion order, but that is currently an implementation detail, and it should not be relied upon. *实际上,在Python 3.6中,普通字典确实会保留插入顺序,但这是当前的实现细节,因此不应依赖它。

If there's a chance of the lists being of different length, you could use map with None like so: 如果列表的长度可能不同,则可以将mapNone一起使用,如下所示:

all_parameters = {"first": ["1a", "1b", "1c", "1d"], "second": ["2a", "2b", "2c"], "third": ["3a", "3b", "3c"]}

final = [dict(zip(all_parameters.keys(), values)) for values in map(None, *all_parameters.values())]

print final

map(None, *all_parameters.values()) gives you a tuple of the values for each key at each index - eg ('1a', '2a', '3a') , and by zipping this to the keys and creating a dictionary, we get the required combination. map(None, *all_parameters.values())为您提供每个索引处每个键的值的元组-例如('1a', '2a', '3a') ,并将其压缩到键上并创建一个字典,我们得到所需的组合。

Note: this will only work in Python 2.x as map changed in 3.x. 注意:这仅适用于Python 2.x,因为在3.x中更改了map For Python 3.x we can use itertools.zip_longest : 对于Python 3.x,我们可以使用itertools.zip_longest

from itertools import zip_longest

all_parameters = {"first": ["1a", "1b", "1c", "1d"], "second": ["2a", "2b", "2c"], "third": ["3a", "3b", "3c"]}

final = [dict(zip(all_parameters.keys(), values)) for values in zip_longest(*all_parameters.values())]

print(final)

In both cases we get: 在这两种情况下,我们得到:

[{'second': '2a', 'third': '3a', 'first': '1a'}, {'second': '2b', 'third': '3b', 'first': '1b'}, {'second': '2c', 'third': '3c', 'first': '1c'}, {'second': None, 'third': None, 'first': '1d'}]

I'm not sure if this is what you want but 我不确定这是否是您想要的

for i in range(len(all_parameters['first'])):
     for position in all_parameters:
         print(position+" "+all_parameters[position][i])

gives an output like this 给出这样的输出

first 1a second 2a third 3a first 1b second 2b third 3b first 1c second 2c third 3c 第一1a第二2a第三3a第一1b第二2b第三3b第一1c第二2c第三3c

This will work only if each dictionary element has a list the same size as the first one. 仅当每个字典元素的列表大小与第一个列表大小相同时,此方法才有效。

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

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