简体   繁体   English

Python:同时具有多个键值对的词典理解

[英]Python: dict comprehension with multiple key-value pairs in the same time

The goal: working analogue of expression 目标:表达模拟

{k1: v1, k2: v2 for k1, k2, v1, v2 in data}

or more particular case {k1: v, k2: v for k1, k2, v, _ in data} 或更具体的情况{k1: v, k2: v for k1, k2, v, _ in data}

that iterates through data only 1 time (in given examples data is iterable object of 4-tuples). 只迭代data 一次 (在给定的示例中, data是4元组的可迭代对象)。

(And similar question about list comprehension, eg [myfunc1(v1), myfunc2(v2) for v1, v2 in data] ). (以及关于列表理解的类似问题,例如[myfunc1(v1), myfunc2(v2) for v1, v2 in data] )。

I can suppose only solution using own iterator: 我可以假设只使用自己的迭代器解决方案:

def getby(iterable_data, iterable_indexes):
    for indexed_data in iterable_data:
        for tupl in iterable_indexes:
            yield tuple(indexed_data[ind] for ind in tupl)
    raise StopIteration

Example of working: list(getby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')], [(0, 1), (2, 1)])) returns [('a', 'b'), ('c', 'b'), ('d', 'e'), ('f', 'e')] . 工作示例: list(getby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')], [(0, 1), (2, 1)]))返回[('a', 'b'), ('c', 'b'), ('d', 'e'), ('f', 'e')] But possible it is slow. 但可能它很慢。

I also can suppose equivalent expression for example above in terms of itertools.chain and itertools.groupby : 我也可以在itertools.chainitertools.groupby方面假设等效表达式如上所述:

list(chain.from_iterable(lst for lst, _ in groupby([('a', 'b', 'c'), ('d', 'e', 'f', 'g')],
                                                   lambda lst: [(lst[0], lst[1]), (lst[2], lst[1])])))

But possible it is ugly. 但可能是丑陋的。

ipython-based comparison of two solution: the first 1000 loops, best of 3: 20.2 ms per loop , the second 1000 loops, best of 3: 4.12 ms per loop , so the second solution really faster. 基于ipython的两种解决方案的比较:前1000个循环,最佳3: 20.2 ms每个循环 ,第二个1000循环,最佳3: 4.12 ms每循环 ,所以第二个解决方案真的更快。 But maybe is more elegant solution exist? 但也许更优雅的解决方案存在?

The comprehension format is strictly limited to one result per iteration. 理解格式严格限于每次迭代一次结果。 You can add extra loops though, to loop over the multiple elements you want to insert: 您可以添加额外的循环,以循环您要插入的多个元素:

{k: v for k1, k2, v1, v2 in data for k, v in ((k1, v1), (k2, v2))}

or your second example: 或者你的第二个例子:

{k: v for k1, k2, v, _ in data for k in (k1, k2)}

which is the equivalent of: 这相当于:

result = {}
for k1, k2, v1, v2 in data:
    for k in (k1, k2):
        result[k] = v

If you can write something out as nested loops, possibly with if statements in between, with just one statement at the innermost level that assigns a key-value pair, then you can express it in a dictionary comprehension. 如果您可以将某些东西写成嵌套循环,可能在两者之间使用if语句,只需要在最内层指定一个键值对的一个语句,那么您可以在字典理解中表达它。

You can do this too with chain.from_iterable() , but then produce lists or tuples with a sequence of key-value pairs, and pass the result to the dict() function: 您也可以使用chain.from_iterable()执行此操作,但随后生成具有一系列键值对的列表或元组,并将结果传递给dict()函数:

dict(chain.from_iterable(((k1, v1), (k2, v2)) for k1, v1, k2, v2 in data))
dict(chain.from_iterable(((k1, v), (k2, v)) for k1, k2, v, _ in data))

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

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